11.2 버전부터 스칼라 서브 쿼리도 버퍼 Pinning 효과가 발생한다.
테스트를 위해 아래와 같이 테이블을 생성하자.
-- 1 DROP TABLE t1 PURGE; DROP TABLE t2 PURGE; CREATE TABLE t1 AS SELECT ROWNUM AS c1, NVL (NULLIF (MOD (ROWNUM, 100), 0), 100) AS c2 FROM XMLTABLE ('1 to 10000'); CREATE TABLE t2 AS SELECT ROWNUM AS c1, ROWNUM AS c2 FROM XMLTABLE ('1 to 10000'); CREATE INDEX t1_x1 ON t1 (c1, c2); CREATE INDEX t1_x2 ON t1 (c2, c1); CREATE INDEX t2_x1 ON t2 (c1); CREATE INDEX t2_x2 ON t2 (c2);
아래 쿼리는 서브 쿼리에 1에서 10000까지의 순번이 입력된다. 서브 쿼리 Caching 효과가 발생하지 않았지만(Starts = 10000), 버퍼 Pinning 효과에 의해 166개의 블록 I/O가 발생했다.
-- 2 SELECT /*+ INDEX(A) */ COUNT ((SELECT /*+ INDEX(X) */ MAX (x.c2) FROM t2 x WHERE x.c1 = a.c1)) FROM t1 a WHERE a.c1 > 0; -------------------------------------------------------------------------- | Id | Operation | Name | Starts | A-Rows | Buffers | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 1 | 193 | | 1 | SORT AGGREGATE | | 10000 | 10000 | 166 | | 2 | TABLE ACCESS BY INDEX ROWID| T2 | 10000 | 10000 | 166 | -- ! |* 3 | INDEX RANGE SCAN | T2_X1 | 10000 | 10000 | 148 | | 4 | SORT AGGREGATE | | 1 | 1 | 193 | |* 5 | INDEX RANGE SCAN | T1_X1 | 1 | 10000 | 27 | --------------------------------------------------------------------------
아래 쿼리는 서브 쿼리에 1, 101, 201 순서의 값이 100회 반복 입력된다. 서브 쿼리 Caching 효과가 발생하지 않았고, 버퍼 Pinning 효과도 발생하지 않아 13,421개의 블록 I/O가 발생했다.
-- 3 SELECT /*+ INDEX(A) */ COUNT ((SELECT /*+ INDEX(X) */ MAX (x.c2) FROM t2 x WHERE x.c1 = a.c1)) FROM t1 a WHERE a.c2 > 0; -------------------------------------------------------------------------- | Id | Operation | Name | Starts | A-Rows | Buffers | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 1 | 13448 | | 1 | SORT AGGREGATE | | 10000 | 10000 | 13421 | | 2 | TABLE ACCESS BY INDEX ROWID| T2 | 10000 | 10000 | 13421 | -- ! |* 3 | INDEX RANGE SCAN | T2_X1 | 10000 | 10000 | 11621 | | 4 | SORT AGGREGATE | | 1 | 1 | 13448 | |* 5 | INDEX RANGE SCAN | T1_X2 | 1 | 10000 | 27 | --------------------------------------------------------------------------
아래 쿼리는 서브 쿼리에 1에서 100까지의 값이 100회씩 입력된다. 서브 쿼리 Caching 효과와 버퍼 Pinning 효과에 의해 9개의 블록 I/O가 발생했다.
-- 4 SELECT /*+ INDEX(A) */ COUNT ((SELECT /*+ INDEX(X) */ MAX (x.c1) FROM t2 x WHERE x.c2 = a.c2)) FROM t1 a WHERE a.c2 > 0; -------------------------------------------------------------------------- | Id | Operation | Name | Starts | A-Rows | Buffers | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 1 | 36 | | 1 | SORT AGGREGATE | | 100 | 100 | 9 | | 2 | TABLE ACCESS BY INDEX ROWID| T2 | 100 | 100 | 9 | -- ! |* 3 | INDEX RANGE SCAN | T2_X2 | 100 | 100 | 8 | | 4 | SORT AGGREGATE | | 1 | 1 | 36 | |* 5 | INDEX RANGE SCAN | T1_X2 | 1 | 10000 | 27 | --------------------------------------------------------------------------
'Oracle > Tuning' 카테고리의 다른 글
소트 머지 조인의 조인 조건에 따른 수행 방식 차이 (0) | 2019.12.28 |
---|---|
계층 코드와 예상 카디널리티 (0) | 2019.12.27 |
SELECT 문과 DML 문의 쿼리 변환 차이 (0) | 2019.11.29 |
POWER 함수의 CPU 연산 #2 (0) | 2019.11.23 |
WINDOW SORT로 인한 성능 저하 (0) | 2019.11.22 |