사용자 도구

사이트 도구


study:oracle:datadb:2week_1:chap4

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
study:oracle:datadb:2week_1:chap4 [2010/05/13 18:36]
starlits
study:oracle:datadb:2week_1:chap4 [2010/05/13 18:52] (현재)
starlits
줄 194: 줄 194:
  
 ==== GROUP BY 뷰의 병합 ==== ==== GROUP BY 뷰의 병합 ====
 +  - Pushing predicate Merge
 +
 +== 뷰쿼리 == 
 +<code sql>
 +CREATE VIEW emp_group_by_deptno
 +AS 
 +     SELECT deptno, AVG(sal) avg_sal, 
 +                 MIN(sal) min_sal, MAX(sal) max_sal
 +     FROM emp
 +     GROUP BY deptno;
 +</code>
 +  - 전체 테이블 로우에 대해 GROUP BY 한 것처럼 보이는 뷰
 +
 +== 액세스쿼리 == 
 +<code sql>
 +SELECT *
 +FROM emp_group_by_deptno
 +WHERE deptno = 10;
 +</code>
 +
 +== 병합 ==
 +<code sql>
 +SELECT deptno, AVG(sal) avg_sal,
 +            MIN(sal) min_sal,MAX(sal) max_sal
 +FROM emp
 +WHERE deptno = 10
 +GROUP BY deptno;
 +</code>
 +  - Complex_view_merging , Optimizer_secure_view_merging 파라메터가 Enabled 되어 있으면 가능하다
 +  - 조건을 만족하는 대상들만 GROUP BY
 +
 +  * <color red>만약 액세스쿼리에서 특정일을 조건으로 주었지만 이 조건이 병합되지 못한다면 ...</color>
 +
 +
 +
 +==== 액세스 쿼리의 병합 ====
 +
 +== 액세스쿼리 ==
 +<code sql>
 +SELECT d.loc,v.avg_sal
 +FROM  dept d, emp_group_by_deptno v
 +WHERE d.deptno = v.deptno
 +AND d.loc = 'London';
 +</code>
 +
 +=== 액세스 쿼리의 정상적인 병합 ===
 +
 +== 병합된 쿼리 ==
 +<code sql>
 +SELECT dept.loc, AVG(sal)
 +FROM dept, emp
 +WHERE dept.deprtno = emp.deptno
 +    AND dept.loc = 'London'
 +GROUP BY dept.rowid, dept.loc; 
 +</code>
 +== 실행계획 ==
 +<code sql>
 +SORT (GROUP BY)
 + NESTED LOOPS
 +   TABLE ACCESS (FULL) OF 'EMP'
 +   TABLE ACCESS (BY INDEX ROWID) OF 'DEPT'
 +     INDEX (RANGE SCAN) OF 'PK_DEPT'(UNIQUE)
 +</code>
 +  - 조건처리가 완료된 후 GROUP BY
 +
 +=== 액세스 쿼리의 병합이 안 일어나는 경우 ===
 +== 액세스쿼리 ==
 +<code sql>
 +SELECT /*+ NO_MERGE(v) */ d.loc,v.avg_sal
 +FROM  dept d, emp_group_by_deptno v
 +WHERE d.deptno = v.deptno
 +AND d.loc = 'London';
 +</code>
 +
 +== 병합쿼리 ==
 +<code sql>
 +SELECT d.loc, v.avg_sal
 +FROM (SELECT deptno, AVG(sal) avg_sal, 
 +                      MIN(sal) min_sal, 
 +                      MAX(sal) max_sal
 +          FROM emp
 +          GROUP BY deptno) v,                    dept d
 +WHERE d.deptno = v.deptno
 +    AND d.loc = 'London'
 +</code>
 +
 +== 실행계획 == 
 +<code sql>
 +HASH JOIN  
 +  TABLE ACCESS (FULL) OF 'DEPT' 
 +   VIEW OF 'EMP_GROUP_BY_DEPTNO'  
 +     SORT (GROUP BY) 
 +       TABLE ACCESS (FULL) OF 'EMP'
 +</code>
 +  - 뷰쿼리를 먼저 처리한 후 조인
 +
 +
 +==== 인라인 서브쿼리의 병합 ====
 +
 +
 +== 뷰쿼리 ==
 +<code sql>
 +CREATE VIEW emp_group_by_deptno
 +AS 
 +     SELECT deptno, AVG(sal) avg_sal, 
 +                 MIN(sal)  min_sal, 
 +                 MAX(sal)  max_sal
 +     FROM emp
 +     GROUP BY deptno;
 +</code>
 +
 +== 액세스쿼리 ==
 +<code sql>
 +SELECT e.ename, e.sal
 +FROM emp e, dept d
 +WHERE (e.deptno, e.sal ) IN (SELECT deptno, avg_sal
 +                                           FROM emp_group_by_deptno)
 +    AND e.deptno = d.deptno
 +    AND d.loc = 'London' ;
 +</code>
 +  - 실행계획을 수립하는 입장에서 보면 반드시 평균급여를 미리 구해야 할 필요는 없다
 +
 +== MERGE 힌트사용시 ==
 +<code sql>
 +FILTER
 + SORT (GROUP BY)  
 +  HASH JOIN  
 +    TABLE ACCESS (FULL) OF 'EMP' 
 +    TABLE ACCESS (FULL) OF 'EMP' 
 +</code>
 +
 +== NO_MERGE 힌트사용시==
 +<code sql>
 +HASH JOIN  
 + TABLE ACCESS (FULL) OF 'EMP'  
 + VIEW  
 +   SORT (GROUP BY)  
 +     TABLE ACCESS (FULL) OF 'EMP'
 +</code>
 +  - 뷰병합을 하지 않는 것이 유리
 +
 +=== 결론 ===
 +  - 처리범위를 줄일 수 있는 조건들이 많아 인라인뷰로 파고들어 가는 것이 일 량을 줄일 수 있다면 뷰병합이 유리
 +  - 파라메터는 기본값을 ‘TRUE’로 하고, 필요하다면 NO_MERGE 힌트를 적용하는 것이 바람직함 
  
 ===== 사용자 정의 바인드 변수의 엿보기(Peeking) ===== ===== 사용자 정의 바인드 변수의 엿보기(Peeking) =====
study/oracle/datadb/2week_1/chap4.1273743366.txt.gz · 마지막으로 수정됨: 2010/05/13 18:36 저자 starlits