09 Outer 조인을 Inner 조인으로 변환
- Outer 조인문을 작성하면서 일부 조건절에 Outer 기호를 빠뜨리면 옵티마이저는 Outer 조인을 Inner 조인문으로 변환하게 된다.
select *
from emp e , dept d
where d.deptno(+) = e.deptno
and d.loc = 'DALLAS'
and e.sal >= 1000
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 250 |
|* 1 | TABLE ACCESS BY INDEX ROWID | EMP | 5 | 160 |
| 2 | NESTED LOOPS | | 5 | 250 |
| 3 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 18 |
|* 4 | INDEX RANGE SCAN | DEPT_IDX | 1 | |
|* 5 | INDEX RANGE SCAN | EMP_DEPTNO_IDX | 5 | |
------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("E"."SAL">=1000)
4 - access("D"."LOC"='DALLAS')
5 - access("D"."DEPTNO"="E"."DEPTNO")
- 옵티마이저가 쿼리 변환을 시행하는 이유는 조인 순서를 자유롭게 결정하기 위함
- Outer NL조인 / Outer 소트머지 조인시 드라이빙 테이블은 항상 Outer 기호가 붙지 않은 쪽으로 고정됨.
- Outer 해시 조인시 자유롭게 조인순서가 바뀌도록 개선됨(10g부터)
- Outer 조인을 써야하는 상황이라면 Outer 기호를 정확히 구사해야 올바른 결과 집합을 얻을 수 있음에 유념
- ANSI Outer 조인문일때는 Outer 기호 대신 조건절 위치에 신경써야 한다.
- Outer 조인에서 Inner쪽 테이블에 대한 필터 조건을 아래처럼 where절에 기술하면 옵티마이저가 Outer 조인을 Inner 조인으로 변환해 버린다.
select *
from dept d left outer join emp e on d.deptno = e.deptno
where e.sal > 1000
- 제대로 된 Outer 조인 결과집합을 얻으려면 sal > 1000 조건을 아래와 같이 on절에 기술
select *
from dept d left outer join emp e on d.deptno = e.deptno and e.sal > 1000
- ANSI Outer 조인문에서 where 절에 기술한 조건이 의미 있게 사용되는 경우는 is null 조건 체크
select *
from dept d left outer join emp e on d.deptno = e.deptno
where e.empno is null
- Outer 필터조건은 on절에 기술하든 where 절에 기술하든 결과 집합이나 성능에 하등에 차이가 없다.