안녕하세요~~
공부하다 보니 .. 궁금한게 생겨서 질문을 올립니다..
EMP_CODE / HR_DATE 에는 각각 인덱스가 있습니다.
1. 바인드 변수 사용법에 관해서 질문있습니다. 특정 입력값일 경우는 INDEX 스캔을 타야하고
다른 입력값시에는 FULL SCAN 을 해야합니다.
SELECT NVL(SUM(SALARY),0)
FROM KT
WHERE (:A = 1 AND EMP_CODE=100 AND HR_DATE||'' = '2000' )
OR
(:A=2 AND HR_DATE||''='2001');
위와 같을 경우 바인드 변수에 상관없이 FULL SCAN을 타게 됩니다.
심지어. BIND 변수 값을 넣지 않아도 디스크 엑세스가 있습니다.
FULL SCAN을 타는 이유가 있을까요..?
그리고 BIND 변수값을 넣지 않아도.. 디스크 액세스가 있다고 책에서 그러는데..
무슨 의미일까요?
( 실행계획상 SORT (AGGREGATE) - TABLE ACCESS(FULL) 이거 두개만 보입니다)
위와같은 경우 보통 OR 을 UNION ALL으로 바꾸어서 튜닝을 하는것 같습니다
2. OR 을 UNION ALL 로 바꾸면 인덱스 스캔 + FULL SCAN 두개의 실행계획이 생성되게 됩니다
FULL SCAN 실행계획 상에 FILTER 실행계획이.. 추가 되는데.. 이유가 뭘까요..?
3.
SELECT NVL(SUM(SALARY),0)
FROM KT
WHERE EMP_CODE CASE WHEN :A= 1 THEN 100 WHEN :A=2 THEN EMP_CODE
AND HR_DATE||'' = CASE WHEN :A=1 THEN '2000' WHEN :A=2 THEN '2001' END;
위와 같은 경우도 FULL SCAN을 타게 됩니다..
개인적으로는.. 무조건 인덱스 SCAN을 탈거 같은데.. 이유가 뭘가요..?
4. 윈도윙절에 대해서 질문 있습니다.
FIRST_VALUE(컬럼명) over (partition by ~ order by ~ rows~~)
SUM(컬럼명) over (partition by ~ order by ~ rows~~)
등 위와같은 경우 rows 절(윈도윙절) 생략시 디폴트 값이.. 어떻게 되는 걸까요?
first_value/last_value의 경우 rows between unbounded preceding and current row 되는거 같고..
sum 의 경우 rows between unbounded preceding and unbounded following 이 되는거 같은데..
함수마다.. default가 다른 걸가요..?
모르는게 많다보니.. 질문이 조금 많네요.. 죄송합니다
혹시 위의 내용중 책 내용을 최대한? 알수없게 햇는데
, 문제가 되는 내용이 있으시면, 리플 달아주시면 해당항목 삭제하도록 하겠습니다
(개인적인 공부 용도이므로.. 이해해 주시면 감사하겠습니다.)
항상 감사합니다
1. 두개의 실행계획으로 분리되려면 OR 가 Concatenate 로 풀려야 합니다.
- 힌트를 이용해 보세요. /*+ use_concat */
2. 필터가 생기는 이유는?
- 조건을 주었으니 당연한거 아닌가요? 조건에 맞는 자료만 필터링
3. 풀스캔 하는 이유는?
- 룰 기반이 아닌 비용기반이기 때문입니다.
- 풀을 선택할지 인덱스를 선택할지는 100% 확신하면 안됩니다.
- 인덱스가 항상 유리한게 아니며 풀스캔이 항상 불리한것도 아니죠.
- 비용을 따져서 적은 쪽을 선택할 것이구요.
- 옵티마이져의 선택이 항상 옳은 것도 아닙니다.
4. 기본값은 같습니다. 단, 기본은 rows 가 아닌 range 입니다.
- range between unbounded preceding and current row
마농님 매번 답변 정말 감사합니다.
2번의 경우 혹시.. 실행계획상에는 table access(full) 만 보이고 밑에 정보상에 filter로 되는 것과 실행계획자체에 filter - table access(full) 차이가 있을까요? 질문의 설명이 부족했던것 같습니다. (실행계획상에는 table access(full) 만 보이고 밑에 정보상에 filter로 되는 것과 실행계획자체에 filter - table access(full)) 이런식으로 나오게 된다고 써있어서 왜 이렇게 구성되는지 궁금해서 올린 질문입니다....
4번 range between 으로 실행된다면.. sum의 경우는... 어떻게.. 해석을 해야할까요 ㅠㅠㅠ
매번 정말 정말 감사합니다
2. FILTER Operation
컬럼 가변 조건이 아닌 고정 조건 (:A = 1) (:A = 2) 이 필터로 표시되는군요.
정확한 동작은 잘 모르겠으나... 미리감치 걸러내는 역할을 하지 않을까? 생각됩니다.
즉 필터 조건을 만족하지 않으면 아예 스캔을 안하는게 아닐까요?
4. range between 으로 실행된다면.. sum의 경우는... 어떻게.. 해석을 해야할까요?
윈도우 절은 앞의 함수부분에 영향을 받는다기보다는 뒤의 Order By 절에 영향을 받습니다.
즉, 정렬 항목에 대한 처리 범위를 지정하고 있는 거구요.
질문자분게서 헷갈려 하신 이유는 테스트 쿼리의 정렬항목에 문제가 있기 때문일 듯 합니다.
예를 들면 다음 두 쿼리의 값을 비교해 보세요.
1. SUM(sal) OVER(PARTITION BY deptno ORDER BY empno) s1
2. SUM(sal) OVER(PARTITION BY deptno ORDER BY deptno) s2
1번은 차곡차곡 누적합이 보일 것이고(부서별 점차 증가)
2번은 한거번에 누적합이 보일 것입니다.(부서별 전체 합)
2번으로 테스트하신 듯 합니다.
2번은 정렬항목이 모두 동일하기 때문에 Range 로 하면 동일 순서이므로 한거번에 합산됩니다.
1번은 정렬항목이 모두 다르기 때문에 Range 로 해도 Rows 와 동일한 결과가 나옵니다.