< 쿼리1 > (머징 전 - 인라인 뷰)
select *
from (select * from emp where job = 'SALESMAN') a,
(select * from dept where loc = 'CHICAGO') b
where a.deptno = b.deptno
< 쿼리2 > (머징 후 - 펼쳐진 형태)
select *
from emp a, dept b
where a.deptno = b.deptno
and a.job = 'SALESMAN'
and b.loc = 'CHICAGO'
쿼리1의 뷰 쿼리 블록은 액세스 쿼리 블록과의 머지 과정을 거쳐 쿼리2와 같은 형태로 변환되는데, 이를 '뷰 Merging'이라고 한다.
(힌트: merge, no_merge)
조건절과 조인문만을 포함하는 단순 뷰는 no_merge 힌트를 사용하지 않는 한 언제든 Merging이 일어난다.
반면 group by 절이나 distinct 연산을 포함하는 복합 뷰는 파라미터 설정 또는 힌트 사용에 의해서만 뷰 Merging이 가능하다.
또한, 집합 연산자, connect by, rownum 등을 포함하는복합 뷰는 아예 뷰 Merging이 불가능하다.
_complex_view_merging 파라미터를 true로 설정하더라도 아래 항목들을 포함하는 복합뷰는 Merging 될 수 없다.
select d.dname, avg_sal_dept
from dept d,
(select deptno, avg(sal) avg_sal_dept
from emp
group by deptno) e
where d.deptno = e.deptno
and d.loc = 'CHICAGO'
-- 복합 뷰 머징 후 변환된 쿼리
select d.dname, avg(sal)
from dept d, emp e
where d.deptno = e.deptno
and d.loc = 'CHICAGO'
group by d.rowid, d.dname
-- 뷰 Merging이 일어난다면 두 쿼리는 똑같이 아래 실행계획을 사용한다.
Execution Plan
--------------------------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=1 Bytes=28)
1 0 HASH (GROUP BY) (Cost=5 Card=1 Bytes=28)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (TABLE)
3 2 NESTED LOOPS (Cost=4 Card=5 Bytes=140)
4 3 TABLE ACCESS (FULL) OF 'DEPT' (TABLE) (Cost=1 Card=5 Bytes=25)
5 3 INDEX (RANGE SCAN) OF 'EMP_IDX' (INDEX) (Cost=0 Card=5)
위 쿼리가 뷰 Merging을 통해 얻을 수 있는 이점은, dept.loc = 'CHICAGO'인 데이터만 선택해서 조인하고, 조인에 성공한 집합만 group by 한다는 데에 있다.
뷰 Merging을 시행했을 때 오히려 비용이 더 증가한다고 판단되거나 부정확한 결과집합이 만들어질 가능성이 있을 때 옵티마이저는 뷰 Merging을 포기한다.
뷰 Merging이 이루어지지 않았을 땐 2차적으로 조건절 Pushing을 시도한다.
하지만 이마저도 실패한다면 뷰 쿼리 블록을 개별적으로 최적화하고, 거기서 생성된 서브플랜을 전체 실행계획을 생성하는 데 사용한다.
NO_MERGE 시 실행계획에 VIEW 오퍼레이션이 나타난다!
-- order by 절을 추가하고 다시 수행해보자
select /*+ leading(d) use_nl(e) */ *
from dept d,
(select /*+ NO_MERGE */ * from emp ORDER BY ENAME) e
where e.deptno = d.deptno
Call Count CPU Time Elapsed Time Disk Query Current Rows
------- ----- -------- ------------ ---- ----- ------- ----
Parse 1 0.000 0.002 0 0 0 0
Execute 1 0.000 0.000 0 0 0 0
Fetch 2 0.000 0.000 0 7 0 14
------- ----- -------- ------------ ---- ----- ------- ----
Total 4 0.000 0.003 0 7 0 14
Rows Row Source Operation
----- ---------------------------------------------------------------
14 NESTED LOOPS (cr=7 pr=0 pw=0 time=169 us)
4 TABLE ACCESS FULL DEPT (cr=4 pr=0 pw=0 time=87 us)
14 VIEW (cr=3 pr=0 pw=0 time=208 us)
56 SORT ORDER BY (cr=3 pr=0 pw=0 time=255 us)
14 TABLE ACCESS FULL EMP (cr=3 pr=0 pw=0 time=61 us)