Oracle/Tuning2018. 3. 13. 09:26

12.2 버전에서 Band Join 기능이 추가되었다. 오라클 문서에서 Band Join이라는 용어를 사용했지만 Sort Merge Join의 기능 개선으로 보인다. 관련 내용을 살펴보자.


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

-- 1
DROP TABLE t1 PURGE;
CREATE TABLE t1 AS SELECT ROWNUM AS c1 FROM XMLTABLE ('1 to 10000');


아래는 12.1 버전에서 수행된 쿼리다. 9.13초가 소요되었다. 6번 SORT JOIN 오퍼레이션에서 PGA를 만번 스캔하여 5천만건(=10000*10000/2)의 데이터를 추출한 다음, 5번 FILTER 오퍼레이션에서 29,998건(=(10000*3)-2)을 남기고 모두 필터링했다. Predicate Information의 필터 조건("B"."C1">="A"."C1"-1)에서 PGA를 끝까지 스캔한 것을 확인할 수 있다.

-- 2
SELECT   /*+ OPTIMIZER_FEATURES_ENABLE('12.1.0.2') */
         a.c1, AVG (b.c1) AS ag
    FROM t1 a, t1 b
   WHERE b.c1 BETWEEN a.c1 - 1 AND a.c1 + 1
GROUP BY a.c1;

-------------------------------------------------------------------------------
| Id  | Operation             | Name | Starts | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |      |      1 |  10000 |00:00:09.13 |      56 |
|   1 |  HASH GROUP BY        |      |      1 |  10000 |00:00:09.13 |      56 |
|   2 |   MERGE JOIN          |      |      1 |  29998 |00:00:09.11 |      56 |
|   3 |    SORT JOIN          |      |      1 |  10000 |00:00:00.01 |      28 |
|   4 |     TABLE ACCESS FULL | T1   |      1 |  10000 |00:00:00.01 |      28 |
|*  5 |    FILTER             |      |  10000 |  29998 |00:00:09.10 |      28 |
|*  6 |     SORT JOIN         |      |  10000 |     50M|00:00:05.52 |      28 |
|   7 |      TABLE ACCESS FULL| T1   |      1 |  10000 |00:00:00.01 |      28 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - filter("B"."C1"<="A"."C1"+1)
   6 - access("B"."C1">="A"."C1"-1)
       filter("B"."C1">="A"."C1"-1)


아래 쿼리는 12.2.0.1 버전에서 수행된 쿼리다. FILTER 오퍼레이션이 사라졌고 0.02초가 소요되었다. 5번 SORT JOIN 오퍼레이션에서 PGA를 만번 스캔하여 29,998건의 데이터를 추출했다. Predicate Information의 필터 조건에 "B"."C1"<="A"."C1"+1 조건이 추가되어 불필요한 범위에 대한 스캔이 사라진 것을 확인할 수 있다.

-- 3
SELECT   /*+ OPTIMIZER_FEATURES_ENABLE('12.2.0.1') */
         a.c1, AVG (b.c1) AS ag
    FROM t1 a, t1 b
   WHERE b.c1 BETWEEN a.c1 - 1 AND a.c1 + 1
GROUP BY a.c1;

------------------------------------------------------------------------------
| Id  | Operation            | Name | Starts | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |      1 |  10000 |00:00:00.02 |      56 |
|   1 |  HASH GROUP BY       |      |      1 |  10000 |00:00:00.02 |      56 |
|   2 |   MERGE JOIN         |      |      1 |  29998 |00:00:00.01 |      56 |
|   3 |    SORT JOIN         |      |      1 |  10000 |00:00:00.01 |      28 |
|   4 |     TABLE ACCESS FULL| T1   |      1 |  10000 |00:00:00.01 |      28 |
|*  5 |    SORT JOIN         |      |  10000 |  29998 |00:00:00.01 |      28 |
|   6 |     TABLE ACCESS FULL| T1   |      1 |  10000 |00:00:00.01 |      28 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - access("B"."C1">="A"."C1"-1)
       filter(("B"."C1"<="A"."C1"+1 AND "B"."C1">="A"."C1"-1))



[2018-10-05]

잘못된 결과 값이 반환되는 버그가 보고되고 있다. 관련 파라미터는 아래와 같다.

NAME                       DEFAULT_VALUE DESCRIPTION
-------------------------- ------------- --------------------------------------------------
_optimizer_band_join_aware TRUE          enable the detection of band join by the optimizer


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

HASH JOIN BUFFERED 오퍼레이션  (0) 2018.06.20
NVL 함수와 스칼라 서브 쿼리  (0) 2018.06.15
TABLE ACCESS BY INDEX ROWID BATCHED 오퍼레이션 #1  (0) 2018.03.09
Top-N 쿼리 개선 사례  (0) 2018.03.07
인덱스와 DML 문  (0) 2018.03.06
Posted by 정희락_