행위

조건절 push

DB CAFE

Dbcafe (토론 | 기여)님의 2021년 11월 12일 (금) 10:22 판
thumb_up 추천메뉴 바로가기


조건절 Pushing

- 뷰를 참조하는 쿼리 블록의 조건절을 뷰 쿼리 블록 안으로 Pushing하는 기능

(옵티마이저가 어떤 이유에서 뷰 Merging에 실패했을 때 2차적으로 시도)


조건절 (Predicate) Pushdown

- 쿼리 블록 밖에 있는 조건들을 쿼리 블록 안쪽으로 밀어 넣음

SELECT DEPTNO, AVG_SAL

 FROM (SELECT DEPTNO, AVG(SAL) AVG_SAL FROM EMP GROUP BY DEPTNO) A

WHERE DETPNO = 30; Execution Plan


 0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=7)
 1    0   SORT (GROUP BY NOSORT) (Cost=2 Card=1 Bytes=7)
 2    1     TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (TABLE) (Cost=2 Card=5 Bytes=35)
 3    2       INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (INDEX) (Cost=1 Card=5)

▶ DEPTNO = 30 조건이 EMP 테이블에도 적용


SELECT /*+ no_merge (a) */

B.DEPTNO, B.DNAME, A.AVG_SAL
 FROM (SELECT DEPTNO, AVG(SAL) AVG_SAL FROM EMP GROUP BY DEPTNO) A

WHERE A.DEPTNO = B.DETPNO

   AND DETPNO = 30;

Execution Plan


 0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=1 Bytes=28)
 1    0   NESTED LOOPS (Cost=3 Card=1 Bytes=28)
 2    1     TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (TABLE) (Cost=1 Card=1 Bytes=13)
 3    2       INDEX (UNIQUE SCAN) OF 'DEPT_PK' (INDEX (UNIQUE)) (Cost=0 Card=1)
 4    1     VIEW (Cost=2 Card=1 Bytes=15)
 5    4       SORT (GROUP BY) (Cost=2 Card=1 Bytes=7)
 6    5         TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (TABLE) (Cost=2 Card=5 Bytes=35)
 7    6           INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (INDEX) (Cost=1 Card=5)


조건절 (Predicate) Pullup

- 쿼리 블록 안에 있는 조건들을 쿼리 블록 바깥 쪽으로 끄집어 냄

(다시 다른 쿼리 블록 안으로 Pushdown 하는데 활용)

SELECT * FROM (SELECT DEPTNO, AVG(SAL) FROM EMP WHERE DEPTNO = 10 GROUP BY DEPTNO) E1, (SELECT DEPTNO, MIN(SAL) FROM EMP GROUP BY DEPTNO) E2 WHERE E1.DEPTNO = E2.DEPTNO; -- DEPTNO = 10 조건을 Pullup 한 다음 E2 블록 안으로 다시 Pushdown Execution Plan


 0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=1 Bytes=65)
 1    0   HASH JOIN (Cost=5 Card=1 Bytes=65)
 2    1     VIEW (Cost=2 Card=1 Bytes=26)
 3    2       HASH (GROUP BY) (Cost=2 Card=1 Bytes=7)
 4    3         TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (TABLE) (Cost=2 Card=5 Bytes=35)
 5    4           INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (INDEX) (Cost=1 Card=5)
 6    1     VIEW (Cost=2 Card=1 Bytes=39)
 7    6       HASH (GROUP BY) (Cost=2 Card=1 Bytes=7)
 8    7         TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (TABLE) (Cost=2 Card=5 Bytes=35)
 9    8           INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (INDEX) (Cost=1 Card=5)


JOIN 조건 (Predicate) Pushdown

- JOIN 조건절을 뷰 쿼리 블록 안으로 밀어 넣음, NL JOIN 수행 중에 드라이빙 테이블에서 읽은 JOIN 컬럼 값을 Inner 쪽 뷰 쿼리 블록 내에서 참조할 수 있도록 하는 기능

  • 조건절 Pushdown의 일종이지만 Pushdown하는 조건절이 상수 조건이 아닌 동적이라는 점에서 다름

SELECT /*+ no_merge(e) push_pred(e) */ *

 FROM DEPT D
          LEFT OUTER JOIN (SELECT EMPNO, ENAME, DEPTNO FROM EMP) E

ON E.DEPTNO = D.DEPTNO WHERE D.LOC = 'CHICAGO'; -- DEPT 테이블에 존재하는 레코드만 group by Execution Plan


 0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=5 Card=4 Bytes=220)
 1    0   NESTED LOOPS (OUTER) (Cost=5 Card=4 Bytes=220)
 2    1     TABLE ACCESS (FULL) OF 'DEPT' (TABLE) (Cost=3 Card=1 Bytes=20)
 3    1     VIEW PUSHED PREDICATE (Cost=2 Card=1 Bytes=35)
 4    3       TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (TABLE) (Cost=2 Card=5 Bytes=80)
 5    4         INDEX (RANGE SCAN) OF 'EMP_DEPTNO_IDX' (INDEX) (Cost=1 Card=5)


  • 관련 힌트

① push_pred : JOIN 조건 Pushdown을 유도

② no_push_pred : JOIN 조건 Pushdown을 방지