Post

<오라클 성능 고도화 원리와 해법2> Ch04-09 Outer 조인을 Inner 조인으로 변환

오라클 성능 고도화 원리와 해법2 - Ch04-09 Outer 조인을 Inner 조인으로 변환

Outer 조인을 작성할 때 일부 조건절에 Outer 기호(+)를 빠뜨리면 Inner 조인할 때와 같은 결과가 나온다. 이럴 때 옵티마이저는 Outer 조인을 Inner 조인으로 바꾸는 쿼리 변환을 실행한다.

옵티마이저가 이러한 쿼리 변환을 하는 이유는 조인 순서를 자유롭게 결정하기 위해서이다. Outer NL 조인, Outer 소트머지 조인 시 드라이빙 테이블은 항상 Outer 기호가 붙지 않은 쪽으로 고정된다. Outer 해시 조인의 경우, 10g부터 자유롭게 조인 순서가 바뀌도록 개선되었지만 9i까지는 해시 조인도 순서가 고정적이었다. 이처럼 조인 순서를 자유롭게 결정하지 못하는 것이 쿼리 최적화에 큰 걸림돌일 수 있다.

그럼에도 Outer 조인 때문에 항상 emp 테이블을 드라이빙해야 한다면 불리한 조건에서 최적화하는 것이 된다. SQL을 작성할 때 불필요한 Outer 조인을 삼가야 하는 이유가 여기에 있다.

Outer 조인을 써야 하는 상황이라면 Outer 기호를 정확히 구사해야 올바른 결과 집합을 얻을 수 있음에 유념하자. ANSI Outer 조인문일 때는 Outer 기호 대신 조건절 위치에 신경을 써야 한다. Outer 조인에서 Inner 쪽 테이블에 대한 필터 조건을 where 절에 기술한다면 Inner 조인할 때와 같은 결과 집합을 얻게 된다. 따라서 옵티마이저가 Outer 조인을 아예 Inner 조인으로 변환해버린다.

1
2
select *
from dept d left outer join emp e on d.deptno = e.deptno where e.sal > 1000

제대로된 Outer 조인 결과 집합을 얻으려면 sal > 1000 조건을 on 절에 기술해주어야 한다.

1
2
select *
from dept d left outer join emp e on d.deptno = e.deptno and e.sal > 1000

ANSI Outer 조인분에서 where 절에 기술한 Inner 쪽 필터 조건이 의미있게 사용되는 경우는 is null 조건을 체크하는 경우 뿐이며, 조인에 실패하는 레코드를 찾고자 할 때 흔히 사용되는 SQL이다.

1
2
3
select *
from dept d left outer join emp e on d.deptno = e.deptno
where e.empno is null

Outer 쪽 필터 조건은 on 절에 기술하든 where 절에 기술하든 결과 집합이나 성능에 하등 차이가 없다.

This post is licensed under CC BY 4.0 by the author.