PUSH JOIN PREDICATE

基本情報

 

パラメータ情報

 

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