2013년 8월 3일 토요일

[Oracle Hint]실행계획 SQL연산(MERGE ANTI-JOIN). 오라클힌트강좌

실행계획 SQL연산(MERGE ANTI-JOIN)

구로디지털 오엔제이프로그래밍실무교육센터

이전 강좌에도 있었지만 Anti-Join Hash Anti-Join, Merge Anti-Join으로 나뉘어 집니다. Merge Anti-Join NOT IN 서브쿼리를 포함하는 쿼리에 적용할 수 있으며 NOT IN의 비교 대상이 되는 컬럼에 대해 NOT NULL 조건을 기술해야 합니다.


-- 실습을 위해 emptest_old를 하나 만들자.

SQL> create table emptest_old as select * from emptest where rownum < 100000;


-- 기본적으로 oracle 11g에서 CBO인 경우
-- 아래 ename, sal 컬럼에 대해서 인덱스는 없다.
-- 힌트구문을 주지 않고 일단 실행하면 FULL SCAN  MERGE ANTI 조인을 이용한다.
-- 엄청 시간이 걸린다. 7

SQL> select  count(e1.ename)
  2  from emptest e1
  3  where (ename, sal) not in (select ename, sal
  4                               from emptest_old e2);

COUNT(E1.ENAME)
---------------
        2400001

   : 00:00:07.32

Execution Plan
| Id  | Operation  | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time    
|   0 | SELECT STATEMENT 
|   1 |  SORT AGGREGATE  
|   2 |   MERGE JOIN ANTI NA
|   3 |    SORT JOIN
|   4 |     TABLE ACCESS FULL| EMPTEST
|*  5 |    SORT UNIQUE      
|   6 |     TABLE ACCESS FULL| EMPTEST_OLD



이번에는 merge anti join을 사용해 보자.
시간이 조금 줄었다.


SQL> select  count(e1.ename)
  2  from emptest e1
  3  where (ename, sal) not in (select ename, sal
  4                               from emptest_old e2
  5                             where  ename is not null
  6                               and  sal   is not null
  7                            )
  8  and   ename is not null
  9  and   sal is not null
 10                 ;

COUNT(E1.ENAME)
---------------
        2400001

   : 00:00:03.82

Execution Plan
----------------------------------------------------------
|   0 | SELECT STATEMENT     |             |     1 |    57 |       | 20170  
|   1 |  SORT AGGREGATE      |             |     1 |    57 |       |
|   2 |   MERGE JOIN ANTI    |             |  2500K|   135M|       | 20170  
|   3 |    SORT JOIN         |             |  2500K|    45M|   134M| 18928  
|*  4 |     TABLE ACCESS FULL| EMPTEST     |  2500K|    45M|       | 
|*  5 |    SORT UNIQUE       |             |   109K|  4077K|    10M|  1243  
|*  6 |     TABLE ACCESS FULL| EMPTEST_OLD |   109K|  4077K|       |  




이번에는 HASH ANT JOIN을 이용해 보자. MERGE ANTI JOIN 보다 빠르다.

SQL> select  count(e1.ename)
  2  from emptest e1
  3  where (ename, sal) not in (select ename, sal
  4                               from emptest_old e2
  5                             where  ename is not null
  6                               and  sal   is not null
  7                            )
  8  and   ename is not null
  9  and   sal is not null;

COUNT(E1.ENAME)
---------------
        2400001

   : 00:00:02.35

Execution Plan
----------------------------------------------------------
|   0 | SELECT STATEMENT
|   1 |  SORT AGGREGATE      
|*  2 |   HASH JOIN RIGHT ANTI|
|*  3 |    TABLE ACCESS FULL  | EMPTEST_OLD
|*  4 |    TABLE ACCESS FULL  | EMPTEST      

댓글 없음:

댓글 쓰기