2018.05.25
PUSH JOIN PREDICATE
目次
- 1. 基本情報
- 2. 参考事項
- 3. 関連情報
- 4. 外部参照
基本情報
パラメータ情報
Syntax : _PUSH_JOIN_PREDICATE 設定方法 : ・Parameter File ・ALTER SYSTEM SET “_PUSH_JOIN_PREDICATE” = TRUE|FALSE ・ALTER SESSION SET “_PUSH_JOIN_PREDICATE” = TRUE|FALSE
バージョンとデフォルト 9iR2 : TRUE 10gR1 : TRUE 10gR2 : TRUE 11g : TRUE
説明
_PUSH_JOIN_PREDIATEパラメータはJoin PredicateをViewのテキストの中にPushする機能を決定します。Oracleは、Viewを使用するクエリに対して優先的にComplex View Mergingを試してみて、これが不可能なビューには、Join Predicate Pushingを試みます。
View Mergingが不可能なビュー(Nonmergeable View)は、次のような機能を使用するViewを意味します。
1. Set operators (UNION, UNION ALL, INTERSECT, MINUS) 2. A CONNECT BY clause 3. A ROWNUM pseudocolumn 4. Aggregate functions (AVG, COUNT, MAX, MIN, SUM) in the select list
Oracleは常にJoin Predicate Pushingを試みますが、Viewの属性に基づいて不可能な場合もあることに注意しなければなりません。例えば、一般的にViewがUNION ALL句またはOUTER JOIN句を使用すると、Join Predicate Pushingが行われないのです。Join Predicate Pushingの動作はOracle Versionごとに異なるため、必ずVersionを確認べきです。
Oracle10gでは、Costに基づいてJoin Predicate Pushing機能を制御する機能が追加され、_OPTIMIZER_PUSH_PRED_COST_BASEDパラメータとして使用するかどうかを指定します。このパラメータの値はデフォルト値Trueです。もし9iバージョンでは、Join Predicate Pushingが動作してQueryの性能が良かったにも関わらず、10gへのアップグレード後、Join Predicate Pushingが動作しない場合は、パラメータの値をFalseに変更することにより、解決することができます。
注意
Join Predicate Pushingの適用例
Join Predicate Pushingの適用例は、以下の通りです。
- UNION構文を使用するView。UNION構文によってView Mergingが不可能である。 CREATE VIEW two_emp_tables (employee_id、last_name、job_id、manager_id、hire_date、salary、 commission_pct、department_id)AS SELECT employee_id、last_name、job_id、manager_id、hire_date、salary、 commission_pct, department_id FROM emp1 UNION SELECT employee_id、last_name、job_id、manager_id、hire_date、 salary、commission_pct、department_id FROM emp2; - Viewをアクセスするクエリ SELECT employee_id、last_name FROM two_emp_tables WHERE department_id=50; - 上記のクエリは、Join Predicate Pushingによって以下のように変換されます。 SELECT employee_id、last_name FROM(SELECT employee_id、last_name、job_id、manager_id、hire_date、 salary、commission_pct、department_id FROM emp1 WHERE department_id=50 - PredicateがSubquery中Pushされます。 UNION SELECT employee_id、last_name、job_id、manager_id、hire_date、 salary、commission_pct、department_id FROM emp2 WHERE department_id=50); - PredicateがSubquery中Pushされます。
誤ったJoin Predicate Pushingによるパフォーマンスの低下
Join Predicate Pushingは非常に望ましい機能であり、一般的に性能を改善させる効果があります。しかし、特定のクエリでは、特に複雑なクエリでは、むしろ誤った実行計画を作成し、逆効果を持っています。この場合には、Join Predicate Pushingを無効にすることで、問題を解決することができます。次のような方法で無効にすることができます。
- _PUSH_JOIN_PREDICATEパラメータをFalseに変更します。 ALTER SESSION SET"_PUSH_JOIN_PREDICATE"= FALSE; SELECT* FROM employees e、( SELECT manager_id FROM employees)v WHERE e.manager_id= v.manager_id(+)AND e.employee_id=100; - NO_PUSH_PREDヒントを使用します。 SELECT/*+ NO_PUSH_PRED(v)*/* FROM employees e、( SELECT manager_id FROM employees)v WHERE e.manager_id= v.manager_id(+)AND e.employee_id=100;
関連情報
1. NO_PUSH_PREDヒント 2. _COMPLEX_VIEW_MERGINGパラメータ 3. _OPTIMIZER_PUSH_PRED_COST_BASEDパラメータ 4. _OPTIMIZER_COST_BASED_TRANSFORMATIONパラメータ 5. _UNNEST_SUBQUERYパラメータ
外部参照
1. http://www.psoug.org/reference/hints.html