Oracle SQLチューニングの基本は実行計画を理解することです。実行計画はツリー構造で、様々なオペレーションから構成されます。
この記事では、VIEW PUSHED PREDICATE オペレーションについて説明します。
VIEW PUSHED PREDICATE オペレーションとはどのようなオペレーションか?
ビューを含むSQLにおいて、ビュー内に結合条件となる述語をプッシュした場合に
使用されるオペレーションです。
検索条件によるデータの絞り込みは、一般に処理のなるべく早い段階で行うことが効率的です。処理内容を変えない範囲で、ビューの中に結合条件となる述語を移動できると、処理の効率化に寄与する場合があります。
実行計画の例
SELECT dept.dname, v.cnt
FROM dept
,(SELECT deptno, count(*) cnt FROM emp GROUP BY deptno) v
WHERE dept.deptno = v.deptno;
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 78 | 15 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 3 | 78 | 15 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL | DEPT | 4 | 52 | 3 (0)| 00:00:01 |
| 3 | VIEW PUSHED PREDICATE | | 1 | 13 | 3 (0)| 00:00:01 |
|* 4 | FILTER | | | | | |
| 5 | SORT AGGREGATE | | 1 | 3 | | |
|* 6 | TABLE ACCESS FULL | EMP | 5 | 15 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter(COUNT(*)>0)
6 - filter("DEPTNO"="DEPT"."DEPTNO")
VIEW PUSHED PREDICATE オペレーションに関するFAQ
VIEW PUSHED PREDICATE オペレーションが使われる条件には何がありますか?
ビューを含むSQLにおいて、ビュー内に結合条件となる述語をプッシュした場合、VIEW PUSHED PREDICATE オペレーションが使用されます。
述語のプッシュは、OracleのCBOが自動的に実行します。
VIEW PUSHED PREDICATE オペレーションを使う実行計画は望ましくないですか?
VIEW PUSHED PREDICATE オペレーションは、ビュー内に結合条件となる述語をプッシュする最適化処理の結果であるため、基本的に望ましい動作です。
極めてまれな例ですが、最適化が良い結果をもたらさない場合もあります。この場合は、NO_PUSH_PREDヒントを指定して、結合条件となる述語をプッシュする最適化処理を抑止します。
SELECT /*+ NO_PUSH_PRED(v) */ dept.dname, v.cnt
FROM dept
,(SELECT deptno, count(*) cnt FROM emp GROUP BY deptno) v
WHERE dept.deptno = v.deptno;
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 117 | 7 (29)| 00:00:01 |
| 1 | MERGE JOIN | | 3 | 117 | 7 (29)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID| DEPT | 4 | 52 | 2 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | PK_DEPT | 4 | | 1 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 3 | 78 | 5 (40)| 00:00:01 |
| 5 | VIEW | | 3 | 78 | 4 (25)| 00:00:01 |
| 6 | HASH GROUP BY | | 3 | 9 | 4 (25)| 00:00:01 |
| 7 | TABLE ACCESS FULL | EMP | 14 | 42 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("DEPT"."DEPTNO"="V"."DEPTNO")
filter("DEPT"."DEPTNO"="V"."DEPTNO")
VIEW PUSHED PREDICATE オペレーションを使う実行計画に誘導するヒントは何ですか?
PUSH_PREDヒントです。ただし、ビュー内に結合条件となる述語をプッシュする最適化処理は自動的に実行されるため、PUSH_PREDヒントを用いて明示的に実行計画を誘導する必要がある状況は少ないです。
参考情報
キーワード
述語のPUSH JPPD join predicate push-down PUSH_PRED NO_PUSH_PRED