문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
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 | ||
+ | | ||
+ | | ||
+ | FROM emp | ||
+ | GROUP BY deptno; | ||
+ | </ | ||
+ | - 전체 테이블 로우에 대해 GROUP BY 한 것처럼 보이는 뷰 | ||
+ | |||
+ | == 액세스쿼리 == | ||
+ | <code sql> | ||
+ | SELECT * | ||
+ | FROM emp_group_by_deptno | ||
+ | WHERE deptno = 10; | ||
+ | </ | ||
+ | |||
+ | == 병합 == | ||
+ | <code sql> | ||
+ | SELECT deptno, AVG(sal) avg_sal, | ||
+ | MIN(sal) min_sal, | ||
+ | FROM emp | ||
+ | WHERE deptno = 10 | ||
+ | GROUP BY deptno; | ||
+ | </ | ||
+ | - Complex_view_merging , Optimizer_secure_view_merging 파라메터가 Enabled 되어 있으면 가능하다 | ||
+ | - 조건을 만족하는 대상들만 GROUP BY | ||
+ | |||
+ | * <color red> | ||
+ | |||
+ | |||
+ | |||
+ | ==== 액세스 쿼리의 병합 ==== | ||
+ | |||
+ | == 액세스쿼리 == | ||
+ | <code sql> | ||
+ | SELECT d.loc, | ||
+ | FROM dept d, emp_group_by_deptno v | ||
+ | WHERE d.deptno = v.deptno | ||
+ | AND d.loc = ' | ||
+ | </ | ||
+ | |||
+ | === 액세스 쿼리의 정상적인 병합 === | ||
+ | |||
+ | == 병합된 쿼리 == | ||
+ | <code sql> | ||
+ | SELECT dept.loc, AVG(sal) | ||
+ | FROM dept, emp | ||
+ | WHERE dept.deprtno = emp.deptno | ||
+ | AND dept.loc = ' | ||
+ | GROUP BY dept.rowid, dept.loc; | ||
+ | </ | ||
+ | == 실행계획 == | ||
+ | <code sql> | ||
+ | SORT (GROUP BY) | ||
+ | | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | TABLE ACCESS (BY INDEX ROWID) OF ' | ||
+ | INDEX (RANGE SCAN) OF ' | ||
+ | </ | ||
+ | - 조건처리가 완료된 후 GROUP BY | ||
+ | |||
+ | === 액세스 쿼리의 병합이 안 일어나는 경우 === | ||
+ | == 액세스쿼리 == | ||
+ | <code sql> | ||
+ | SELECT /*+ NO_MERGE(v) */ d.loc, | ||
+ | FROM dept d, emp_group_by_deptno v | ||
+ | WHERE d.deptno = v.deptno | ||
+ | AND d.loc = ' | ||
+ | </ | ||
+ | |||
+ | == 병합쿼리 == | ||
+ | <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 = ' | ||
+ | </ | ||
+ | |||
+ | == 실행계획 == | ||
+ | <code sql> | ||
+ | HASH JOIN | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | VIEW OF ' | ||
+ | SORT (GROUP BY) | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | </ | ||
+ | - 뷰쿼리를 먼저 처리한 후 조인 | ||
+ | |||
+ | |||
+ | ==== 인라인 서브쿼리의 병합 ==== | ||
+ | |||
+ | |||
+ | == 뷰쿼리 == | ||
+ | <code sql> | ||
+ | CREATE VIEW emp_group_by_deptno | ||
+ | AS | ||
+ | | ||
+ | | ||
+ | | ||
+ | FROM emp | ||
+ | GROUP BY deptno; | ||
+ | </ | ||
+ | |||
+ | == 액세스쿼리 == | ||
+ | <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 = ' | ||
+ | </ | ||
+ | - 실행계획을 수립하는 입장에서 보면 반드시 평균급여를 미리 구해야 할 필요는 없다 | ||
+ | |||
+ | == MERGE 힌트사용시 == | ||
+ | <code sql> | ||
+ | FILTER | ||
+ | SORT (GROUP BY) | ||
+ | HASH JOIN | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | </ | ||
+ | |||
+ | == NO_MERGE 힌트사용시== | ||
+ | <code sql> | ||
+ | HASH JOIN | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | | ||
+ | SORT (GROUP BY) | ||
+ | TABLE ACCESS (FULL) OF ' | ||
+ | </ | ||
+ | - 뷰병합을 하지 않는 것이 유리 | ||
+ | |||
+ | === 결론 === | ||
+ | - 처리범위를 줄일 수 있는 조건들이 많아 인라인뷰로 파고들어 가는 것이 일 량을 줄일 수 있다면 뷰병합이 유리 | ||
+ | - 파라메터는 기본값을 ‘TRUE’로 하고, 필요하다면 NO_MERGE 힌트를 적용하는 것이 바람직함 | ||
===== 사용자 정의 바인드 변수의 엿보기(Peeking) ===== | ===== 사용자 정의 바인드 변수의 엿보기(Peeking) ===== |