Oracle/Tuning2018. 12. 10. 16:01

ROLLUP을 사용한 인라인 뷰는 JPPD가 동작하지 않는다.


테스트를 위해 아래와 같이 테이블을 생성하자.

-- 1
DROP TABLE t1 PURGE;
DROP TABLE t2 PURGE;

CREATE TABLE t1 (c1 NUMBER);
CREATE TABLE t2 (c1 NUMBER, c2 NUMBER, c3 NUMBER);
CREATE INDEX t2_x1 ON t2 (c1);

GROUP BY는 JPPD가 정상적으로 동작한다. 

-- 2
SELECT /*+ LEADING(A) USE_NL(B) NO_MERGE(B) PUSH_PRED(B) */
       *
  FROM t1 a
     , (SELECT   c1, SUM (c3) AS c3
            FROM t2
        GROUP BY c1) b
 WHERE b.c1 = a.c1;

-------------------------------------------------
| Id  | Operation                       | Name  |
-------------------------------------------------
|   0 | SELECT STATEMENT                |       |
|   1 |  NESTED LOOPS                   |       |
|   2 |   TABLE ACCESS FULL             | T1    |
|   3 |   VIEW PUSHED PREDICATE         |       |
|*  4 |    FILTER                       |       |
|   5 |     SORT AGGREGATE              |       |
|   6 |      TABLE ACCESS BY INDEX ROWID| T2    |
|*  7 |       INDEX RANGE SCAN          | T2_X1 |
-------------------------------------------------


ROLLUP을 사용한 경우 JPPD가 동작하지 않는다.[각주:1] SORT GROUP BY ROLLUP 오퍼레이션으로 동작하는 CUBE, GROUPING SET 모두 마찬가지다.

-- 3
SELECT /*+ LEADING(A) USE_NL(B) NO_MERGE(B) PUSH_PRED(B) */
       *
  FROM t1 a
     , (SELECT   c1, SUM (c3) AS c3
            FROM t2
        GROUP BY ROLLUP (c1, c2)) b
 WHERE b.c1 = a.c1;

---------------------------------------
| Id  | Operation              | Name |
---------------------------------------
|   0 | SELECT STATEMENT       |      |
|   1 |  NESTED LOOPS          |      |
|   2 |   TABLE ACCESS FULL    | T1   |
|*  3 |   VIEW                 |      |
|   4 |    SORT GROUP BY ROLLUP|      |
|   5 |     TABLE ACCESS FULL  | T2   |
---------------------------------------

12.1 이후 버전은 LATERAL 뷰를 사용할 수 있다. b.c1 IS NOT NULL 조건을 추가해야 동일한 결과를 얻을 수 있다.

-- 4
SELECT /*+ LEADING(A) USE_NL(B) NO_MERGE(B) PUSH_PRED(B) NO_DECORRELATE(@SUB) */
       *
  FROM t1 a
     , LATERAL
       (SELECT   /*+ QB_NAME(SUB) */
                 x.c1, SUM (x.c3) AS c3
            FROM t2 x
           WHERE x.c1 = a.c1
        GROUP BY ROLLUP (x.c1, x.c2)) b
 WHERE b.c1 IS NOT NULL;

-------------------------------------------------------------------
| Id  | Operation                               | Name            |
-------------------------------------------------------------------
|   0 | SELECT STATEMENT                        |                 |
|   1 |  NESTED LOOPS                           |                 |
|   2 |   TABLE ACCESS FULL                     | T1              |
|   3 |   VIEW                                  | VW_LAT_A18161FF |
|*  4 |    FILTER                               |                 |
|   5 |     SORT GROUP BY ROLLUP                |                 |
|   6 |      TABLE ACCESS BY INDEX ROWID BATCHED| T2              |
|*  7 |       INDEX RANGE SCAN                  | T2_X1           |
-------------------------------------------------------------------


  1. 18.3 버전에서도 동작하지 않는다. [본문으로]

'Oracle > Tuning' 카테고리의 다른 글

DB 링크 튜닝 기법  (0) 2018.12.13
JPPD와 서브 쿼리 팩토링  (0) 2018.12.11
FK로 인한 DML 성능 저하  (0) 2018.12.08
INDEX SCAN 방식에 따른 사용자 정의 함수  (0) 2018.12.07
TIMESTAMP 타입과 SYSTIMESTAMP 함수  (0) 2018.12.01
Posted by 정희락_