1:M조인을 하는 테이블 중 조인에만 참가하고 조건절이나 Select List에서 참조되지 않는 1쪽 테이블이 있다면 결과집합에 영향을 미치지 않으므로 M쪽 테이블만 읽도록 1쪽 테이블을 읽는 동작을 제거하는 쿼리변환이다. (10g부터 작동)
================================================================
Dept, Emp테이블간의 릴레이션을 맺지않아 옵티마이져가 두 집합간의 조인카디널리티를 알 수 없을 때는 조인제거 쿼리변환이 작동하지 않는다.
orcl:WOONG >
1 select e.empno, e.ename, e.deptno, e.sal, e.hiredate
2 from dept d, emp e
3 where d.deptno = e.deptno;
경 과: 00:00:00.01
Execution Plan
----------------------------------------------------------
Plan hash value: 3009604424
-------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 952 |
| 1 | NESTED LOOPS | | 14 | 952 |
| 2 | TABLE ACCESS FULL| EMP | 14 | 770 |
|* 3 | INDEX UNIQUE SCAN| DEPTNO_PK | 1 | 13 |
-------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("D"."DEPTNO"="E"."DEPTNO")
Dept, Emp테이블간의 릴레이션을 맺어진 이후에야 쿼리변환이 작동하지 않는다. 또한 Null허용컬럼을 대상으로 조인제거를 하여 테이블을 제거하면 결과값이 달라질 수 있으므로 내부적으로 조건절(("E"."DEPTNO" IS NOT NULL)이 추가된 것을 확인할 수 있다.
orcl:WOONG >
1 alter table dept add
2 constraint deptno_pk primary key(deptno);
orcl:WOONG >
1 select e.empno, e.ename, e.deptno, e.sal, e.hiredate
2 from dept d, emp e
3 where d.deptno = e.deptno;
경 과: 00:00:00.00
Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932
-------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 770 |
|* 1 | TABLE ACCESS FULL| EMP | 14 | 770 |
-------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("E"."DEPTNO" IS NOT NULL)
Null 관련 제약이나 FK제약이 필요 없는 Outer join의 경우 10g에서는 조인제거가 동작하지 않지만 11g에서는 조인제거가 정상적으로 동작한다.(어떻게 논리적인 전제가 없음에도 불구하고 동작할까?)
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
orcl:WOONG >
1 select e.empno, e.ename, e.sal, e.hiredate
2 from emp e, dept d
3 where d.deptno(+) = e.deptno;
경 과: 00:00:00.00
Execution Plan
--------------------------------------------------------
Plan hash value: 1655207496
--------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
--------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 952 |
| 1 | NESTED LOOPS OUTER| | 14 | 952 |
| 2 | TABLE ACCESS FULL| EMP | 14 | 770 |
|* 3 | INDEX UNIQUE SCAN| DEPTNO_PK | 1 | 13 |
--------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("D"."DEPTNO"(+)="E"."DEPTNO")
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for 32-bit Windows: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
orcl:WOONG11 >
1 select e.empno, e.ename, e.sal, e.hiredate
2 from emp e, dept d
3 where d.deptno(+) = e.deptno;
경 과: 00:00:00.00
Execution Plan
--------------------------------------------------
--------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
--------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 770 |
| 1 | TABLE ACCESS FULL| EMP | 14 | 770 |
--------------------------------------------------
================================================================