Oracle/Tuning2018. 11. 3. 08:57

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  |
----------------------------------


  1. emp 테이블에 deptno 테이블의 deptno 열을 참조하는 FK 제약 조건이 존재한다. [본문으로]
Posted by 정희락_