{code:SQL | title= 예제 | borderStyle=solid} ALTER SESSION SET EVENTS '10053 trace name context forever, level 1'; |
select A.EMPLOYEE_ID, A.FIRST_NAME, A.LAST_NAME, A.EMAIL, B.DEPARTMENT_ID
from EMPLOYEE a,
(select B.DEPARTMENT_ID, B.DEPARTMENT_NAME
from DEPARTMENT b
where B.DEPARTMENT_ID = :v_deptno ) b
where a.DEPARTMENT_ID = b.DEPARTMENT_ID;
ALTER SESSION SET EVENTS '10053 trace name context off';
============
Plan Table
============
Id | Operation | Name | Rows | Bytes | Cost | Time |
0 | SELECT STATEMENT | 1 | ||||
1 | NESTED LOOPS | 10 | 330 | 0 | ||
2 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | 3 | 0 | |
3 | TABLE ACCESS BY INDEX ROWID | EMPLOYEE | 10 | 300 | 0 | |
4 | INDEX RANGE SCAN | EMP_DEPARTMENT_IX | 10 | 0 |
* Plan상에서 View가 사라졌다. Transformer가 SQL을 아래처럼 바꿈|
|{code:SQL|title= SQL변환 |borderStyle=solid}
SELECT a.employee_id, a.first_name, a.last_name, a.email, b.department_id
FROM employee a, department b
WHERE a.department_id = b.department_id
AND b.department_id = :v_deptno
AND a.department_id = :v_deptno; -- View Merging이 발생함으로써 Transitive Predicate(조건절 전이)가 발생하였다.
{code:SQL | title= Merge | borderStyle=solid} outline Data: /*+ BEGIN_Outline_DATA ... 중간생략 MERGE(@"SEL$2") ...중간생략 END_Outline_DATA */ {code} * 오라클이 내부적으로 Merge 힌트를 사용한 것을 알 수 있다. * 오라클은 이와같이 내부적인 힌트를 사용함으로써 Transformation을 수행한다. * DBMS_XPLAN의 outline Data를 분석해보면 많은 경우에 오라클의 내부적인 힌트의 사용을 관찰할 수 있다. |
{code:SQL | title= Join Elimination (JE) | borderStyle=solid} ************************* Join Elimination (JE) ************************* ... 중간생략 CVM: Considering view merge in query block SEL$1 (#0) OJE: Begin: find best directive for query block SEL$1 (#0) OJE: End: finding best directive for query block SEL$1 (#0) CVM: Checking validity of merging in query block SEL$2 (#0) CVM: Considering view merge in query block SEL$2 (#0) OJE: Begin: find best directive for query block SEL$2 (#0) OJE: End: finding best directive for query block SEL$2 (#0) CVM: Merging SPJ view SEL$2 (#0) into SEL$1 (#0) --SEL$2가 해체되어 SEL$1으로 통합 Registered qb: SEL$F5BB74E1 0x10902870 (VIEW MERGE SEL$1; SEL$2) {code} * 아쉬운점: 10053 Trace에는 SVM을 CVM이라고 표현하고 있다. |
| title= CVM | borderStyle=solid} 없음{code} |
| title= Transitive Predicate | borderStyle=solid} ************************** Predicate Move-Around (PM) ************************** PM: PM bypassed: Outer query contains no views. PM: PM bypassed: Outer query contains no views. query block SEL$F5BB74E1 (#0) unchanged FPD: Considering simple filter push in query block SEL$F5BB74E1 (#0) "A"."DEPARTMENT_ID"="B"."DEPARTMENT_ID" AND "B"."DEPARTMENT_ID"=TO_NUMBER(:B1) try to generate transitive predicate from check constraints for query block SEL$F5BB74E1 (#0) finally: "A"."DEPARTMENT_ID"=TO_NUMBER(:B1) AND "B"."DEPARTMENT_ID"=TO_NUMBER(:B2) {code} * EMPLOYEE 테이블이 뷰와 조인하지 않고 DEPARTMENT 테이블과 직접 조인이 발생함으로써 Transitive Predicate가 발생될 수 있다. |