11.2 버전에서 Join Elimination 쿼리 변환이 동작하지 않는 사례를 발견했다. FK 제약 조건을 생성하는 경우가 흔치 않으므로 자주 볼 수 있는 사례는 아니다.
아래 쿼리는 Join Elimination 쿼리 변환이 발생했다. FK 제약 조건인 deptno 열로 조인했고1, dept 테이블의 열을 조회하기 않았기 때문에 deptno 테이블과의 조인이 불필요한 것이다.
-- 1
SELECT a.*
FROM emp a
LEFT OUTER
JOIN dept b
ON b.deptno = a.deptno;
----------------------------------
| Id | Operation | Name |
----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS FULL| EMP |
----------------------------------
Outline Data
-------------
ELIMINATE_JOIN(@"SEL$9E43CB6E" "B"@"SEL$1")
아래 쿼리는 11.2 버전에서 Join Elimination 쿼리 변환이 발생하지 않는다. OUTER JOIN의 ON 절에 1 = 1 조건을 기술했을 뿐인데 쿼리 변환이 동작하지 않는 점이 흥미롭다. 해당 현상은 INNER JOIN에서는 발생하지 않으며, 12.1 이상 버전에서는 쿼리 변환이 정상적으로 동작한다.
-- 2
SELECT a.*
FROM emp a
LEFT OUTER
JOIN dept b
ON 1 = 1
AND b.deptno = a.deptno;
---------------------------------------
| Id | Operation | Name |
---------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | NESTED LOOPS OUTER | |
| 2 | TABLE ACCESS FULL | EMP |
| 3 | VIEW | |
|* 4 | INDEX UNIQUE SCAN| PK_DEPT |
---------------------------------------
1 = 1 조건을 WHERE 절에 기술하면 Join Elimination 쿼리 변환이 정상적으로 동작한다. 결론적으로 11.2 이하 버전에서는 OUTER JOIN의 ON 절에 1 = 1 등의 불필요한 조건을 기술하지 않는 편이 바람직하다.
-- 3
SELECT a.*
FROM emp a
LEFT OUTER
JOIN dept b
ON b.deptno = a.deptno
WHERE 1 = 1;
----------------------------------
| Id | Operation | Name |
----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS FULL| EMP |
----------------------------------- emp 테이블에 deptno 테이블의 deptno 열을 참조하는 FK 제약 조건이 존재한다. [본문으로]
'Oracle > Tuning' 카테고리의 다른 글
| 계층 쿼리 절의 수행 방식 (0) | 2018.11.03 |
|---|---|
| JPPD(Join Predicate PushDown) 쿼리 변환이 동작하지 않는 사례 (0) | 2018.11.03 |
| 사용자 정의 함수의 동작 방식 (0) | 2018.10.27 |
| 사용자 정의 함수의 실행 계획 (0) | 2018.10.27 |
| 트레이스 파일 병합 (0) | 2018.10.27 |

