ヘッダーをスキップ
Oracle® Databaseパフォーマンス・チューニング・ガイド
11gリリース2 (11.2)
B56312-06
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

12 EXPLAIN PLANの使用方法

この章では、実行計画について紹介し、SQL文EXPLAIN PLANを解説し、その出力の解釈方法を説明します。さらに、アプリケーションのパフォーマンス特性を制御するアウトラインを管理するプロシージャを示します。

この章には次の項があります。

12.1 EXPLAIN PLANについて

EXPLAIN PLAN文は、SELECTUPDATEINSERTおよびDELETE文に関して、オプティマイザによって選択された実行計画を表示します。文の実行計画とは、その文を実行するためにデータベースで行われる一連の処理です。

行ソース・ツリーは、実行計画の中核です。このツリーには、次の情報が表示されます。

  • 文によって参照される表の順序

  • 文で言及される各表へのアクセス方法

  • 文の結合操作の影響を受ける表の結合方法

  • フィルタ、ソート、集計などのデータ操作

PLAN TABLEには、行ソース・ツリーの他、次の情報が含まれています。

  • 最適化。各操作のコストとカーディナリティについて。

  • パーティション化。アクセスされたパーティションのセットなど。

  • パラレル実行。結合入力の配分方法など。

EXPLAIN PLANの結果により、オプティマイザが特定の実行計画(たとえば、ネステッド・ループ結合)を選択するかどうかを判断できます。また、オプティマイザの決定(たとえば、オプティマイザがハッシュ結合でなくネステッド・ループ結合を選択した理由)および問合せのパフォーマンスについても理解できます。

12.1.1 実行計画の変化理由

問合せオプティマイザを使用すると、実行計画は基礎となるオプティマイザ入力が変化するたびに変化します。EXPLAIN PLANの出力は、EXPLAINされたSQL文をOracle Databaseがどのように実行するかを示します。実行環境とEXPLAIN PLAN環境が異なるため、SQL文を実際に実行する際の計画は、EXPLAIN PLANの実行計画とは異なる可能性があります。


注意:

実行計画の変更から生じる可能性があるSQLパフォーマンスの低下を回避するには、SQL計画の管理を使用することを検討してください。

実行計画は、次の理由により異なります。

12.1.1.1 スキーマの相違

  • 実行とEXPLAIN PLANのデータベースが異なる場合。

  • 文をEXPLAINするユーザーが、文を実行するユーザーとは異なる場合。2人のユーザーが同じデータベース内の異なるオブジェクトを指していれば、異なる実行計画が発生します。

  • 2つの操作間でスキーマが変更された場合(多くは索引の変更)。

12.1.1.2 コストの相違

スキーマが同じであっても、コストに違いがある場合、オプティマイザは異なる実行計画を選択する可能性があります。コストに影響を与えるいくつかの要因には次のものがあります。

  • データ量と統計

  • バインド変数の型と値

  • グローバルまたはセッション・レベルで設定された初期化パラメータ

12.1.2 排除行数の最少化

EXPLAIN PLANを調べることにより、次の場合の排除行数を確認できます。

  • 全表スキャン

  • 選択性のないレンジ・スキャン

  • 遅延した述語フィルタ

  • 誤った結合順序

  • 遅延したフィルタ処理

たとえば、次のEXPLAIN PLANでは、最後のステップは非常に選択性のないレンジ・スキャンです。このレンジ・スキャンは76563回実行され、11432983行にアクセスし、アクセスした行の99パーセントを排除して76563行を保持します。11432983行にアクセスした結果、必要な行が76563行のみであると認識された理由について考えます。

例12-1 EXPLAIN PLAN内の排除行数の確認

Rows      Execution Plan
--------  ----------------------------------------------------
      12  SORT AGGREGATE
       2   SORT GROUP BY
   76563    NESTED LOOPS
   76575     NESTED LOOPS
      19      TABLE ACCESS FULL CN_PAYRUNS_ALL
   76570      TABLE ACCESS BY INDEX ROWID CN_POSTING_DETAILS_ALL
   76570       INDEX RANGE SCAN (object id 178321)
   76563     TABLE ACCESS BY INDEX ROWID CN_PAYMENT_WORKSHEETS_ALL
11432983      INDEX RANGE SCAN (object id 186024)

12.1.3 実行計画以外の考慮事項

実行計画の操作のみでは、よく調整された文とうまく機能しない文を区別できません。たとえば、文による索引の使用がEXPLAIN PLAN出力で示されたとしても、その文が効率的に機能するとはかぎりません。効率的でない索引もあります。この場合、次のことを調べる必要があります。

  • 使用される索引の列

  • その索引の選択性(アクセスされる表の一部)

EXPLAIN PLANを使用してアクセス計画を判断し、後からテストによってそれが最適な計画であることを確認するのが最もよい方法です。計画を評価する際は、文の正確なリソース使用量を調べてください。

12.1.3.1 V$SQL_PLANビューの使用

EXPLAIN PLANコマンドを実行して計画を表示するのみではなく、V$SQL_PLANビューを使用してSQL文の実行計画を表示できます。

文の実行後に、V$SQL_PLANビューを問い合せて計画を表示できます。V$SQL_PLANには、共有SQL領域に格納されたすべての文の実行計画が含まれます。その定義は、PLAN_TABLEに類似しています。「PLAN_TABLE列」を参照してください。

V$SQL_PLANEXPLAIN PLANよりも優れている点は、特定の文の実行に使用されたコンパイル環境を知らなくてもかまわないということです。EXPLAIN PLANの場合は、文の実行時に同じ計画を取得するために同一環境をセットアップする必要があります。

V$SQL_PLAN_STATISTICSビューは、出力行数や経過時間など、計画に含まれる操作ごとに実際の実行統計を提供します。出力行数を除き、すべての統計は累積されます。たとえば、結合操作の統計には、2つの入力の統計も含まれます。V$SQL_PLAN_STATISTICSの統計は、STATISTICS_LEVEL初期化パラメータをALLに設定してコンパイルされたカーソルに使用できます。

V$SQL_PLAN_STATISTICS_ALLビューを使用すると、行数と経過時間に関してオプティマイザにより提供される見積りを並べて表示できます。このビューでは、各カーソルのV$SQL_PLANおよびV$SQL_PLAN_STATISTICS情報が結合されます。


関連項目:

  • V$SQL_PLAN_MONITORビューの詳細は、「リアルタイムSQL監視」を参照してください。

  • V$SQL_PLANビューの詳細は、『Oracle Databaseリファレンス』を参照してください。

  • STATISTICS_LEVEL初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。


12.1.4 EXPLAIN PLANの制限事項

Oracle Databaseでは、日付バインド変数の暗黙的な型変換を実行する文でのEXPLAIN PLANをサポートしません。一般にバインド変数では、EXPLAIN PLANが実際の実行計画を表していない場合があります。

TKPROFは、SQL文のテキストからバインド変数の型を判断することはできません。型はCHARACTERであると想定され、これ以外の場合はエラー・メッセージが表示されます。この制限事項は、SQL文に適切な型変換を入れることで対処できます。

12.2 PLAN_TABLE出力表

PLAN_TABLEは、グローバル一時表に対するパブリック・シノニムとして自動的に作成されます。この一時表に、すべてのユーザーに対するEXPLAIN PLAN文の出力が保持されます。PLAN_TABLEは、EXPLAIN PLAN文が実行計画について記述している行を挿入するデフォルトのサンプル出力表です。表内の列の詳細は、「PLAN_TABLE列」を参照してください。

PLAN_TABLE表は各ユーザーに対し自動的に設定されますが、SQLスクリプトcatplan.sqlを使用して、グローバル一時表とPLAN_TABLEシノニムを手動で作成できます。このスクリプトの名前と位置は、使用するオペレーティング・システムによって異なります。UNIXおよびLinux上では、このスクリプトは$ORACLE_HOME/rdbms/adminディレクトリにあります。

たとえば、SQL*Plusセッションを開始し、SYSDBA権限で接続し、そして次のようにスクリプトを実行します。

@$ORACLE_HOME/rdbms/admin/catplan.sql

データベースのバージョンを更新した場合は、列が変更される可能性があるため、ローカルのPLAN_TABLE表を削除して再作成することをお薦めします。表を指定する場合は、スクリプトの実行が失敗したり、TKPROFが失敗する場合があります。

名前PLAN_TABLEを使用しない場合は、catplan.sqlスクリプトの実行後に新しいシノニムを作成します。たとえば、次のようにします。

CREATE OR REPLACE PUBLIC SYNONYM my_plan_table for plan_table$

12.3 EXPLAIN PLANの実行

SQL文をEXPLAINする場合は、文の直前でEXPLAIN PLAN FOR句を使用します。たとえば、次のようにします。

EXPLAIN PLAN FOR
  SELECT last_name FROM employees;

計画をEXPLAINしたものがPLAN_TABLE表に挿入されます。PLAN_TABLEから実行計画を選択できるようになります。「PLAN_TABLE出力の表示」を参照してください。

12.3.1 EXPLAIN PLANでの文の指定

複数の文があるときは、文の識別子を指定し、その識別子で特定の実行計画を識別できます。SET STATEMENT IDを使用する前に、その文と同じ識別子を持つ既存の行を削除してください。

例12-2の場合は、st1が文の識別子として指定されています。

例12-2 STATEMENT ID句でのEXPLAIN PLANの使用方法

EXPLAIN PLAN
  SET STATEMENT_ID = 'st1' FOR
SELECT last_name FROM employees;

12.3.2 EXPLAIN PLANでの別の表の指定

INTO句を指定して、別の表を指定できます。

例12-3 INTO句でのEXPLAIN PLANの使用方法

EXPLAIN PLAN
  INTO my_plan_table
 FOR
SELECT last_name FROM employees;

INTO句を使用する場合は、文の識別子を指定できます。

EXPLAIN PLAN
   SET STATEMENT_ID = 'st1'
   INTO my_plan_table
 FOR
SELECT last_name FROM employees;

関連項目:

EXPLAIN PLAN構文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

12.4 PLAN_TABLE出力の表示

計画をEXPLAINした後、Oracle Databaseから提供される次のSQLスクリプトまたはPL/SQLパッケージを使用して最新のPLAN TABLE出力を表示します。

  • UTLXPLS.SQL

    このスクリプトは、シリアル処理のためのPLAN TABLE出力を表示します。例11-14「EXPLAIN PLAN出力」は、UTLXPLS.SQLスクリプトを使用した場合のPLAN TABLE出力の例です。

  • UTLXPLP.SQL

    このスクリプトは、パラレル実行列を含むPLAN TABLE出力を表示します。

  • DBMS_XPLAN.DISPLAYテーブル・ファンクション

    このファンクションは、PLAN TABLE出力を表示するオプションを受け入れます。指定できるのは次のとおりです。

    • PLAN_TABLEとは別の表を使用している場合のPLAN TABLE名

    • EXPLAIN PLANに文の識別子を設定した場合の文の識別子

    • 詳細レベルを決定するフォーマット・オプション: BASICSERIALおよびTYPICALALL

    DBMS_XPLANを使用してPLAN_TABLE出力を表示するいくつかの例を次に示します。

    SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
    
    SELECT PLAN_TABLE_OUTPUT 
      FROM TABLE(DBMS_XPLAN.DISPLAY('MY_PLAN_TABLE', 'st1','TYPICAL'));
    

    関連項目:

    DBMS_XPLANパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

12.4.1 PLAN_TABLE出力のカスタマイズ

文の識別子を指定した場合は、PLAN_TABLEを問い合せるための独自のスクリプトを書くことができます。たとえば、次のようにします。

  • START WITH ID = 0およびSTATEMENT_IDを指定します。

  • CONNECT BY句を使用して親から子へツリーを移動します。結合キーは、STATEMENT_ID = PRIOR STATEMENT_IDおよびPARENT_ID = PRIOR IDです。

  • 疑似列LEVEL(CONNECT BYに関連付けられている)を使用して子をインデントします。

    SELECT cardinality "Rows",
       lpad(' ',level-1)||operation||' '||options||' '||object_name "Plan"
      FROM PLAN_TABLE
    CONNECT BY prior id = parent_id
            AND prior statement_id = statement_id
      START WITH id = 0
            AND statement_id = 'st1'
      ORDER BY id;
    
       Rows Plan
    ------- ----------------------------------------
            SELECT STATEMENT
             TABLE ACCESS FULL EMPLOYEES
    

    Rows列のNULLは、オプティマイザが表に統計を持っていないことを示します。表をANALYZEすると、次の内容が表示されます。

       Rows Plan
    ------- ----------------------------------------
      16957 SELECT STATEMENT
      16957  TABLE ACCESS FULL EMPLOYEES
    

    COSTも選択できます。これは、実行計画を比較する場合や、オプティマイザが複数の中からある実行計画を選択した理由を理解する場合に便利です。


    注意:

    これらの単純な例は、再帰的SQLの場合には有効ではありません。

12.5 EXPLAIN PLAN出力の読み方

この項では、EXPLAIN PLANの例を使用して実行計画を説明します。例12-4の文によって、実行計画が表示されます。

例12-4 EXPLAIN PLANを表示する文

SELECT PLAN_TABLE_OUTPUT 
  FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'statement_id','BASIC'));

この文の出力例を、例12-5および例12-6に示します。

例12-5 文ID ex_plan1のEXPLAIN PLAN

EXPLAIN PLAN 
  SET statement_id = 'ex_plan1' FOR
SELECT phone_number FROM employees
 WHERE phone_number LIKE '650%';

---------------------------------------
| Id  | Operation         | Name      |
---------------------------------------
|   0 | SELECT STATEMENT  |           |
|   1 |  TABLE ACCESS FULL| EMPLOYEES |
---------------------------------------

この計画は、SELECT文の実行を示します。表employeesは、全表スキャンでアクセスされます。

  • employeesのすべての行がアクセスされ、各行がWHERE句の条件に基づいて評価されます。

  • SELECT文により、WHERE句の条件に一致する行が戻されます。

例12-6 文ID ex_plan2のEXPLAIN PLAN

EXPLAIN PLAN 
  SET statement_id = 'ex_plan2' FOR
SELECT last_name FROM employees
 WHERE last_name LIKE 'Pe%';

SELECT PLAN_TABLE_OUTPUT 
  FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'ex_plan2','BASIC'));

----------------------------------------
| Id  | Operation        | Name        |
----------------------------------------
|   0 | SELECT STATEMENT |             |
|   1 |  INDEX RANGE SCAN| EMP_NAME_IX |
----------------------------------------

この計画は、SELECT文の実行を示します。

  • データベースでは、EMP_NAME_IXのレンジ・スキャンによってWHERE句の条件を評価します。

  • SELECT文により、WHERE句の条件を満たす行が戻されます。

12.6 EXPLAIN PLANによるパラレル実行の表示

パラレル問合せのチューニングは、パラレルでない問合せのチューニングの場合と同様に駆動表を選択することにより、開始されます。ただし、選択を管理するルールは異なります。パラレルでない問合せの場合は、通常、制限条件が適用された後に最も少ない行が生成される駆動表が最適です。少数の行は、一意でない索引を使用して大きな表に結合されます。たとえば、CUSTOMERACCOUNTおよびTRANSACTIONで構成された表階層の場合について考えます。

CUSTOMERが最も小さな表で、TRANSACTIONが最も大きな表です。通常のOLTP問合せでは、特定の顧客のアカウントに関する取引情報が取得できます。問合せはCUSTOMER表から駆動されます。この場合の目標は、論理I/Oを最少化することです。それにより、通常、物理I/OやCPUタイムを含むその他の重要なリソースも最少化されます。

パラレル問合せの場合は、データベースでパラレル問合せを使用できるため、通常では最も大きな表が駆動表として選択されます。この場合はパラレル問合せを使用するのは効率的ではありません。各表から最終的にアクセスされる行がごくわずかであるためです。ここで、前月に特定のタイプの取引を持つすべての顧客を識別する必要が生じた場合を考えてみます。顧客表には制限条件がないため、問合せはTRANSACTION表から行うほうが効率的です。データベースは、TRANSACTION表から取り出した行をACCOUNT表に結合し、最終的にはCUSTOMER表に結合します。この場合、ACCOUNTおよびCUSTOMER表で使用される索引は、通常、最初の問合せで使用される一意でない索引ではなく、選択性の高い主キーまたは一意の索引になります。TRANSACTION表は大きく、列に選択性がないため、TRANSACTION表から駆動されるパラレル問合せを使用したほうが有効です。

パラレル操作には次のものがあります。

  • PARALLEL_TO_PARALLEL

  • PARALLEL_TO_SERIAL

    PARALLEL_TO_SERIAL操作は、パラレル操作からの行が問合せコーディネータによって使用される場合、常に発生するステップです。この問合せでは発生しない他の種類の操作には、SERIAL操作があります。このような操作が発生した場合は、これらもボトルネックになる可能性があるため、パフォーマンスの向上のためにパラレル操作を検討します。

  • PARALLEL_FROM_SERIAL

  • PARALLEL_TO_PARALLEL

    通常は、各ステップのワークロードがほぼ同じであるかぎり、PARALLEL_TO_PARALLEL操作によって最適なパフォーマンスが得られます。

  • PARALLEL_COMBINED_WITH_CHILD

  • PARALLEL_COMBINED_WITH_PARENT

    PARALLEL_COMBINED_WITH_PARENT操作は、ステップを親ステップと同時に実行する場合に発生します。

パラレル・ステップで多数の行が生成される場合、行の生成される速さにQCの処理が追いつかない場合があります。この状況を改善する方法はほとんどありません。


関連項目:

表12-1「PLAN_TABLE列」OTHER_TAG列を参照してください。

12.6.1 EXPLAIN PLANによるパラレル問合せの表示

EXPLAIN PLANをパラレル問合せとともに使用すると、データベースは1つのパラレル計画をコンパイルおよび実行します。この計画は、QC計画にパラレル・サポートに固有の行ソースを割り当てることで、シリアル計画から導出されます。2つのスレーブ・セットPQモデルで要求される、表キューの行ソース(PX SendおよびPX Receive)、グラニュル・イテレータおよびバッファ・ソートは、パラレル計画に直接挿入されます。この計画は、パラレルで実行された場合はすべてのスレーブで、またシリアルで実行された場合はすべてのQCで、まったく同じ計画となります。

例12-7は、パラレル問合せのEXPLAIN PLANを説明するための単純な問合せです。

例12-7 パラレル問合せのEXPLAIN PLAN

CREATE TABLE emp2 AS SELECT * FROM employees;
ALTER TABLE emp2 PARALLEL 2;

EXPLAIN PLAN FOR
  SELECT SUM(salary) FROM emp2 GROUP BY department_id;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
--------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name     | Rows  | Bytes | Cost (%CPU) |    TQ  |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |          |   107 |  2782 |     3 (34)  |        |      |            |
|   1 |  PX COORDINATOR          |          |       |       |             |        |      |            |
|   2 |   PX SEND QC (RANDOM)    | :TQ10001 |   107 |  2782 |     3 (34)  |  Q1,01 | P->S | QC (RAND)  |
|   3 |    HASH GROUP BY         |          |   107 |  2782 |     3 (34)  |  Q1,01 | PCWP |            |
|   4 |     PX RECEIVE           |          |   107 |  2782 |     3 (34)  |  Q1,01 | PCWP |            |
|   5 |      PX SEND HASH        | :TQ10000 |   107 |  2782 |     3 (34)  |  Q1,00 | P->P | HASH       |
|   6 |       HASH GROUP BY      |          |   107 |  2782 |     3 (34)  |  Q1,00 | PCWP |            |
|   7 |        PX BLOCK ITERATOR |          |   107 |  2782 |     2 (0)   |  Q1,00 | PCWP |            |
|   8 |         TABLE ACCESS FULL| EMP2     |   107 |  2782 |     2 (0)   |  Q1,00 | PCWP |            |
--------------------------------------------------------------------------------------------------------

第1のスレーブ・セットによってEMP2表がパラレルにスキャンされる間に、第2のスレーブ・セットによってGROUP BYが集計されます。PX BLOCK ITERATOR行ソースは、スキャンのワークロードがパラレル・スキャン・スレーブ間で分割されるように、EMP2表が複数のピースに分割されることを表します。PX SENDおよびPX RECEIVE行ソースは、2つのスレーブ・セットをパラレル・スキャンからの行フローとして接続するパイプを表し、HASH表キューを介して再びパーティション化されてから、上位スレーブ・セットにより読み取られて集計されます。PX SEND QC行ソースは、QCにランダム(RAND)な順序で送信される集計値を表します。PX COORDINATOR行ソースは、計画ツリーで下に表示されるパラレル計画を制御しスケジュールするQC(問合せコーディネータ)を表します。

12.7 EXPLAIN PLANによるビットマップ索引の表示

ビットマップ索引を使用する索引行ソースは、索引のタイプを示す語BITMAPとともにEXPLAIN PLAN出力に表示されます。例12-8の問合せおよび計画の例を検討します。

例12-8 ビットマップ検索によるEXPLAIN PLAN

EXPLAIN PLAN FOR
SELECT * FROM t
WHERE c1 = 2 
AND c2 <> 6 
OR c3 BETWEEN 10 AND 20;
SELECT STATEMENT
   TABLE ACCESS T BY INDEX ROWID
      BITMAP CONVERSION TO ROWID
         BITMAP OR
            BITMAP MINUS
               BITMAP MINUS
                  BITMAP INDEX C1_IND SINGLE VALUE
                  BITMAP INDEX C2_IND SINGLE VALUE
               BITMAP INDEX C2_IND SINGLE VALUE
            BITMAP MERGE
               BITMAP INDEX C3_IND RANGE SCAN

この例では、述語c1=2によってビットマップが生成され、そこから減算が行われます。このビットマップから、c2 = 6に対応するビットマップ内のビットが減算されます。同様に、c2 IS NULLに対応するビットマップ内のビットが減算され、この計画の中に2つのMINUS行ソースがある理由がわかります。NULL減算は、NOT NULL制約が列に設定されていないかぎり、意味上の正確さを保つために必要です。TO ROWIDSオプションは、表アクセスに必要な行IDを生成します。


注意:

ビットマップ結合索引を使用した問合せは、ビットマップ結合索引のアクセス・パスを指示します。ビットマップ結合索引の操作は、ビットマップ索引と同じです。

12.8 EXPLAIN PLANによる結果キャッシュの表示

問合せにresult_cacheヒントが含まれる場合、ResultCache演算子が実行計画に挿入されます。

例として、次の問合せを検討します。

select /*+ result_cache */ deptno, avg(sal) 
from emp 
group by deptno;

この問合せのEXPLAIN PLANを表示するには、次のコマンドを使用します。

EXPLAIN PLAN FOR 
select /*+ result_cache */ deptno, avg(sal) 
from emp 
group by deptno;
select PLAN_TABLE_OUTPUT from TABLE (DBMS_XPLAN.DISPLAY());

この問合せのEXPLAIN PLAN出力は、次のようになります。

---------------------------------------------------------------------------------------------
| Id  | Operation           | Name                        |Rows |Bytes |Cost(%CPU)|Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |                             | 11  | 77   |  4 (25)  | 00:00:01|
|   1 |  RESULT CACHE       |b06ppfz9pxzstbttpbqyqnfbmy   |     |      |          |         |
|   2 |   HASH GROUP BY     |                             | 11  | 77   |  4 (25)  | 00:00:01|
|   3 |    TABLE ACCESS FULL| EMP                         |107  | 749  |  3 (0)   | 00:00:01|
---------------------------------------------------------------------------------------------

このEXPLAIN PLANでは、ResultCache演算子はそのCacheId(b06ppfz9pxzstbttpbqyqnfbmy)によって識別されます。このCacheIdを使用して、V$RESULT_CACHE_OBJECTSビューに対して問合せを実行できます。

12.9 EXPLAIN PLANによるパーティション・オブジェクトの表示

EXPLAIN PLANを使用して、特定の問合せのパーティション化オブジェクトへのOracle Databaseのアクセス方法を表示します。

プルーニング後にアクセスされたパーティションは、PARTITION START列とPARTITION STOP列に表示されます。レンジ・パーティションの行ソース名は、PARTITION RANGEです。ハッシュ・パーティションの場合、行ソース名はPARTITION HASHです。

結合されるいずれかの表のPLAN TABLEのDISTRIBUTION列にPARTITION(KEY)が存在する場合、結合はパーシャル・パーティション・ワイズ結合を使用して実装されます。パーシャル・パーティション・ワイズ結合が可能なのは、結合される表のいずれかが結合列でパーティション化されており、かつ、表がパラレル化されている場合です。

EXPLAIN PLAN出力の結合行ソースの前にパーティション行ソースがある場合、結合はフル・パーティション・ワイズ結合を使用して実装されます。フル・パーティション・ワイズ結合が可能なのは、両方の結合表がそれぞれの結合列でパーティション化されている場合のみです。次に、いくつかの種類のパーティションに対する実行計画の例を示します。

12.9.1 EXPLAIN PLANによるレンジ・パーティション化およびハッシュ・パーティション化の表示の例

hire_dateで範囲ごとにパーティション化されている次のemp_range表を参考に、プルーニングの表示方法を例示します。Oracle Databaseサンプル・スキーマの表employeesおよびdepartmentsが存在することを想定しています。

CREATE TABLE emp_range 
PARTITION BY RANGE(hire_date) 
( 
PARTITION emp_p1 VALUES LESS THAN (TO_DATE('1-JAN-1992','DD-MON-YYYY')),
PARTITION emp_p2 VALUES LESS THAN (TO_DATE('1-JAN-1994','DD-MON-YYYY')),
PARTITION emp_p3 VALUES LESS THAN (TO_DATE('1-JAN-1996','DD-MON-YYYY')),
PARTITION emp_p4 VALUES LESS THAN (TO_DATE('1-JAN-1998','DD-MON-YYYY')),
PARTITION emp_p5 VALUES LESS THAN (TO_DATE('1-JAN-2001','DD-MON-YYYY')) 
) 
AS SELECT * FROM employees; 

最初の例では、次の文を検討します。

EXPLAIN PLAN FOR 
  SELECT * FROM emp_range; 

次のような結果が表示されます。

---------------------------------------------------------------------------------
| Id  | Operation           | Name      | Rows  | Bytes | Cost  | Pstart| Pstop |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |           |   105 | 13965 |     2 |       |       |
|   1 |  PARTITION RANGE ALL|           |   105 | 13965 |     2 |     1 |     5 |
|   2 |   TABLE ACCESS FULL | EMP_RANGE |   105 | 13965 |     2 |     1 |     5 |
---------------------------------------------------------------------------------

データベースでは、表アクセス行ソースに加えて、パーティション行ソースが作成されます。これが、アクセスされるパーティションのセットに対して繰り返されます。この例では、述語がプルーニングに使用されていないので、パーティション・イテレータはすべてのパーティション(ALLオプション)を対象とします。PLAN_TABLEPARTITION_START列とPARTITION_STOP列は、1~5のすべてのパーティションへのアクセスを示します。

次の例では、次の文を検討します。

EXPLAIN PLAN FOR 
  SELECT * FROM emp_range 
  WHERE hire_date >= TO_DATE('1-JAN-1996','DD-MON-YYYY');

--------------------------------------------------------------------------------------
| Id  | Operation                | Name      | Rows  | Bytes | Cost  | Pstart| Pstop |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |           |     3 |   399 |     2 |       |       |
|   1 |  PARTITION RANGE ITERATOR|           |     3 |   399 |     2 |     4 |     5 |
|*  2 |   TABLE ACCESS FULL      | EMP_RANGE |     3 |   399 |     2 |     4 |     5 |
--------------------------------------------------------------------------------------

前の例では、hire_dateの述語を使用してその他のパーティションをプルーニングするため、パーティション行ソースはパーティション4から5を反復します。

最後に、次の文を検討します。

EXPLAIN PLAN FOR 
  SELECT * FROM emp_range 
  WHERE hire_date < TO_DATE('1-JAN-1992','DD-MON-YYYY'); 

------------------------------------------------------------------------------------
| Id  | Operation              | Name      | Rows  | Bytes | Cost  | Pstart| Pstop |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |           |     1 |   133 |     2 |       |       |
|   1 |  PARTITION RANGE SINGLE|           |     1 |   133 |     2 |     1 |     1 |
|*  2 |   TABLE ACCESS FULL    | EMP_RANGE |     1 |   133 |     2 |     1 |     1 |
------------------------------------------------------------------------------------

この例では、パーティション1のみがアクセスされ、それがコンパイル時に認識されます。したがって、パーティション行ソースは必要ありません。

12.9.1.1 ハッシュ・パーティション化の計画

ハッシュ・パーティション・オブジェクトでは、パーティション行ソース名がPARTITION RANGEではなくPARTITION HASHであることを除き、同じ情報が表示されます。また、ハッシュ・パーティション化では、プルーニングが可能なのは等価述語かINリスト述語を使用している場合のみです。

12.9.2 コンポジット・パーティション・オブジェクトでのプルーニング情報の例

Oracle Databaseでのコンポジット・パーティション・オブジェクトのプルーニング情報の表示を、hiredateでレンジ・パーティション化され、deptnoでハッシュ・サブパーティション化された表emp_compにおいて説明します。

CREATE TABLE emp_comp PARTITION BY RANGE(hire_date) 
      SUBPARTITION BY HASH(department_id) SUBPARTITIONS 3 
( 
PARTITION emp_p1 VALUES LESS THAN (TO_DATE('1-JAN-1992','DD-MON-YYYY')),
PARTITION emp_p2 VALUES LESS THAN (TO_DATE('1-JAN-1994','DD-MON-YYYY')),
PARTITION emp_p3 VALUES LESS THAN (TO_DATE('1-JAN-1996','DD-MON-YYYY')),
PARTITION emp_p4 VALUES LESS THAN (TO_DATE('1-JAN-1998','DD-MON-YYYY')),
PARTITION emp_p5 VALUES LESS THAN (TO_DATE('1-JAN-2001','DD-MON-YYYY')) 
) 
AS SELECT * FROM employees; 

最初の例では、次の文を検討します。

EXPLAIN PLAN FOR 
  SELECT * FROM emp_comp; 

--------------------------------------------------------------------------------
| Id  | Operation           | Name     | Rows  | Bytes | Cost  | Pstart| Pstop |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |          | 10120 |  1314K|    78 |       |       |
|   1 |  PARTITION RANGE ALL|          | 10120 |  1314K|    78 |     1 |     5 |
|   2 |   PARTITION HASH ALL|          | 10120 |  1314K|    78 |     1 |     3 |
|   3 |    TABLE ACCESS FULL| EMP_COMP | 10120 |  1314K|    78 |     1 |    15 |
--------------------------------------------------------------------------------

この例では、Oracle Databaseがコンポジット・オブジェクトの全パーティションの全サブパーティションにアクセスする場合の計画を示します。この目的を達成するために、2つのパーティション行ソースを使用します。1つはパーティションを反復するレンジ・パーティション行ソースで、もう1つはアクセスされる各パーティションのサブパーティションを反復するハッシュ・パーティション行ソースです。

次の例では、プルーニングを実行しないため、レンジ・パーティション行ソースはパーティション1から5を反復します。各パーティション内では、ハッシュ・パーティション行ソースは現在のパーティションのサブパーティション1から3を反復します。その結果、表アクセス行ソースがサブパーティション1から15にアクセスします。つまり、コンポジット・オブジェクトのすべてのサブパーティションにアクセスすることになります。

EXPLAIN PLAN FOR 
  SELECT * FROM emp_comp 
  WHERE hire_date = TO_DATE('15-FEB-1998', 'DD-MON-YYYY'); 

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost  | Pstart| Pstop |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |    20 |  2660 |    17 |       |       |
|   1 |  PARTITION RANGE SINGLE|          |    20 |  2660 |    17 |     5 |     5 |
|   2 |   PARTITION HASH ALL   |          |    20 |  2660 |    17 |     1 |     3 |
|*  3 |    TABLE ACCESS FULL   | EMP_COMP |    20 |  2660 |    17 |    13 |    15 |
-----------------------------------------------------------------------------------

この例では、最後のパーティション5のみがアクセスされます。このパーティションはコンパイル時に認識されるので、計画では表示する必要がありません。ハッシュ・パーティション行ソースは、そのパーティション内のすべてのサブパーティションのアクセスを表示します。つまり、サブパーティション1から3が表示されることになりますが、これはemp_comp表のサブパーティション13から15に変換されます。

次に、次の文を検討します。

EXPLAIN PLAN FOR 
  SELECT * FROM emp_comp WHERE department_id = 20; 

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost  | Pstart| Pstop |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |   101 | 13433 |    78 |       |       |
|   1 |  PARTITION RANGE ALL   |          |   101 | 13433 |    78 |     1 |     5 |
|   2 |   PARTITION HASH SINGLE|          |   101 | 13433 |    78 |     3 |     3 |
|*  3 |    TABLE ACCESS FULL   | EMP_COMP |   101 | 13433 |    78 |       |       |
-----------------------------------------------------------------------------------

この例では、述語deptno = 20によって各パーティション内のハッシュ・ディメンションでプルーニングが使用可能なので、Oracleは単一のサブパーティションにアクセスするだけで済みます。そのサブパーティションの番号はコンパイル時に認識されるので、ハッシュ・パーティション行ソースは必要ありません。

最後に、次の文を検討します。

VARIABLE dno NUMBER; 
EXPLAIN PLAN FOR 
  SELECT * FROM emp_comp WHERE department_id = :dno; 

-----------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Bytes | Cost  | Pstart| Pstop |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |   101 | 13433 |    78 |       |       |
|   1 |  PARTITION RANGE ALL   |          |   101 | 13433 |    78 |     1 |     5 |
|   2 |   PARTITION HASH SINGLE|          |   101 | 13433 |    78 |   KEY |   KEY |
|*  3 |    TABLE ACCESS FULL   | EMP_COMP |   101 | 13433 |    78 |       |       |
-----------------------------------------------------------------------------------

最後の2つの例は、deptno = 20がdepartment_id = :dnoに置き換えられたこと以外は同じです。この最後の場合、サブパーティションの番号はコンパイル時には不明であり、ハッシュ・パーティション行ソースが割り当てられます。Oracle Databaseでは、各パーティション内の1つのサブパーティションにのみアクセスするため、この行ソースのオプションはSINGLEです。PARTITION_STARTおよびPARTITION_STOPKEYに設定されます。これは、Oracle Databaseによりサブパーティションの番号が実行時に判別されることを意味します。

12.9.3 パーシャル・パーティション・ワイズ結合の例

次の例では、emp_range_didがパーティション化列department_idで結合され、パラレル化されます。dept2表がパーティション化されていないことにより、パーシャル・パーティション・ワイズ結合が使用可能になります。Oracle Databaseでは、結合前にdept2表を動的にパーティション化します。

例12-9 レンジ・パーティション化を使用したパーシャル・パーティション・ワイズ結合

CREATE TABLE dept2 AS SELECT * FROM departments;
ALTER TABLE dept2 PARALLEL 2;

CREATE TABLE emp_range_did PARTITION BY RANGE(department_id)
   (PARTITION emp_p1 VALUES LESS THAN (150),
    PARTITION emp_p5 VALUES LESS THAN (MAXVALUE) )
  AS SELECT * FROM employees;

ALTER TABLE emp_range_did PARALLEL 2;

EXPLAIN PLAN FOR 
SELECT /*+ PQ_DISTRIBUTE(d NONE PARTITION) ORDERED */ e.last_name, 
                     d.department_name 
   FROM emp_range_did e , dept2 d 
   WHERE e.department_id = d.department_id ;
-------------------------------------------------------------------------------------------------------------
| Id| Operation                    |Name         |Rows | Bytes |Cost|Pstart|Pstop|   TQ  |IN-OUT|PQ Distrib |
-------------------------------------------------------------------------------------------------------------
|  0| SELECT STATEMENT             |             | 284 | 16188 |  6 |      |     |       |      |            
|  1|  PX COORDINATOR              |             |     |       |    |      |     |       |      |           |
|  2|   PX SEND QC (RANDOM)        |:TQ10001     | 284 | 16188 |  6 |      |     | Q1,01 | P->S | QC (RAND) |
|* 3|    HASH JOIN                 |             | 284 | 16188 |  6 |      |     | Q1,01 | PCWP |           |
|  4|     PX PARTITION RANGE ALL   |             | 284 |  7668 |  2 |    1 |   2 | Q1,01 | PCWC |           |
|  5|      TABLE ACCESS FULL       |EMP_RANGE_DID| 284 |  7668 |  2 |    1 |   2 | Q1,01 | PCWP |           |
|  6|     BUFFER SORT              |             |     |       |    |      |     | Q1,01 | PCWC |           |
|  7|      PX RECEIVE              |             |  21 |   630 |  2 |      |     | Q1,01 | PCWP |           |
|  8|       PX SEND PARTITION (KEY)|:TQ10000     |  21 |   630 |  2 |      |     |       | S->P |PART (KEY) |
|  9|        TABLE ACCESS FULL     |DEPT2        |  21 |   630 |  2 |      |     |       |      |           |
------------------------------------------------------------------------------------------------------------

この実行計画は、dept2表がシリアルにスキャンされ、emp_range_didの同じパーティション化列値(department_id)を持つすべての行が、パーティション・キーを示すPART (KEY)、表キューを介して、パーシャル・パーティション・ワイズ結合を実行する同じスレーブに送られることを示します。

次の例では、emp_compがパーティション化列で結合され、パラレル化されます。dept2表がパーティション化されていないことにより、パーシャル・パーティション・ワイズ結合が使用可能になります。データエースは、結合前にdept2表を動的にパーティション化します。

例12-10 コンポジット・パーティション化を使用したパーシャル・パーティション・ワイズ結合

ALTER TABLE emp_comp PARALLEL 2; 

EXPLAIN PLAN FOR 
SELECT /*+ PQ_DISTRIBUTE(d NONE PARTITION) ORDERED */ e.last_name, 
         d.department_name 
  FROM emp_comp e, dept2 d 
 WHERE e.department_id = d.department_id;
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
-------------------------------------------------------------------------------------------------------------
| Id | Operation                   | Name    | Rows | Bytes | Cost |Pstart|Pstop|    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT            |         |  445 | 17800 |    5 |      |     |        |      |           |
|  1 |  PX COORDINATOR             |         |      |       |      |      |     |        |      |           |
|  2 |   PX SEND QC (RANDOM)       |:TQ10001 |  445 | 17800 |    5 |      |     |  Q1,01 | P->S | QC (RAND) |
|* 3 |    HASH JOIN                |         |  445 | 17800 |    5 |      |     |  Q1,01 | PCWP |           |
|  4 |     PX PARTITION RANGE ALL  |         |  107 |  1070 |    3 |    1 |   5 |  Q1,01 | PCWC |           |
|  5 |      PX PARTITION HASH ALL  |         |  107 |  1070 |    3 |    1 |   3 |  Q1,01 | PCWC |           |
|  6 |       TABLE ACCESS FULL     |EMP_COMP |  107 |  1070 |    3 |    1 |  15 |  Q1,01 | PCWP |           |
|  7 |     PX RECEIVE              |         |   21 |   630 |    1 |      |     |  Q1,01 | PCWP |           |
|  8 |      PX SEND PARTITION (KEY)|:TQ10000 |   21 |   630 |    1 |      |     |  Q1,00 | P->P |PART (KEY) |
|  9 |       PX BLOCK ITERATOR     |         |   21 |   630 |    1 |      |     |  Q1,00 | PCWC |           |
| 10 |        TABLE ACCESS FULL    |DEPT2    |   21 |   630 |    1 |      |     |  Q1,00 | PCWP |           |
-------------------------------------------------------------------------------------------------------------

この計画は、オプティマイザが2つの列の一方からパーシャル・パーティション・ワイズ結合を選択することを示します。PX SENDのノード・タイプはPARTITION(KEY)で、PQ Distrib列にはパーティション・キーを示すテキストPART (KEY)が含まれています。これは、EMP_COMPのスキャンと結合を実行するパラレル・スレーブに送られる結合列department_idに基づいて、dept2表が再びパーティション化されることを意味します。

例12-9および例12-10では、問合せオプティマイザがこの問合せのコストに基づいて異なる計画を選択する可能性があるため、PQ_DISTRIBUTEヒントにより、パーシャル・パーティション・ワイズ結合が明示的に強制されています。

12.9.4 フル・パーティション・ワイズ結合の例

次の例では、emp_compdept_hashがハッシュ・パーティション化列で結合されます。これにより、フル・パーティション・ワイズ結合が使用可能になります。PARTITION HASH行ソースが、PLAN TABLE出力の結合行ソースの上に表示されます。

PX PARTITION HASH行ソースはPLAN TABLE出力で結合行ソースの上に表示されますが、PX PARTITION RANGE行ソースはemp_compのスキャンにまたがって表示されます。各パラレル・スレーブは、emp_compのハッシュ・パーティション全体とdept_hashのパーティション全体の結合を実行します。

例12-11 フル・パーティション・ワイズ結合

CREATE TABLE dept_hash
   PARTITION BY HASH(department_id)
   PARTITIONS 3
   PARALLEL 2
   AS SELECT * FROM departments;

EXPLAIN PLAN FOR SELECT /*+ PQ_DISTRIBUTE(e NONE NONE) ORDERED */ e.last_name,
       d.department_name
  FROM emp_comp e, dept_hash d
 WHERE e.department_id = d.department_id;
-------------------------------------------------------------------------------------------------------------
| Id | Operation                  | Name      | Rows |Bytes |Cost |Pstart|Pstop |   TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------
|  0 | SELECT STATEMENT           |           |  106 | 2544 |   8 |      |      |       |      |            |
|  1 |  PX COORDINATOR            |           |      |      |     |      |      |       |      |            |
|  2 |   PX SEND QC (RANDOM)      | :TQ10000  |  106 | 2544 |   8 |      |      | Q1,00 | P->S | QC (RAND)  |
|  3 |    PX PARTITION HASH ALL   |           |  106 | 2544 |   8 |    1 |    3 | Q1,00 | PCWC |            |
|* 4 |     HASH JOIN              |           |  106 | 2544 |   8 |      |      | Q1,00 | PCWP |            |
|  5 |      PX PARTITION RANGE ALL|           |  107 | 1070 |   3 |    1 |    5 | Q1,00 | PCWC |            |
|  6 |       TABLE ACCESS FULL    | EMP_COMP  |  107 | 1070 |   3 |    1 |   15 | Q1,00 | PCWP |            |
|  7 |      TABLE ACCESS FULL     | DEPT_HASH |   27 |  378 |   4 |    1 |    3 | Q1,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------

12.9.5 INLIST ITERATORおよびEXPLAIN PLANの例

INLIST ITERATOR操作は、索引がINリスト述語を実装する場合に、EXPLAIN PLAN出力に表示されます。たとえば、次のようにします。

SELECT * FROM emp WHERE empno IN (7876, 7900, 7902);

EXPLAIN PLAN出力は次のようになります。

OPERATION          OPTIONS           OBJECT_NAME
----------------   ---------------   -------------- 
SELECT STATEMENT
INLIST ITERATOR
TABLE ACCESS       BY ROWID          EMP
INDEX              RANGE SCAN        EMP_EMPNO

INLIST ITERATOR操作は、INリスト述語内の各値に対して、計画内の次の操作を反復します。パーティション表およびパーティション索引には3種類のINリスト列が使用可能ですが、これについては次の項で説明します。

12.9.5.1 INリスト列が索引列である場合

INリスト列empnoが索引列で、パーティション列ではない場合、計画は次のようになります(INリスト演算子は表操作の前に表示されますが、パーティションの操作よりは後に表示されます)。

OPERATION        OPTIONS              OBJECT_NAME PARTITION_START PARTITION_STOP
---------------- ------------         ----------- --------------- -------------- 
SELECT STATEMENT 
PARTITION RANGE  ALL                               KEY(INLIST)     KEY(INLIST)
INLIST ITERATOR
TABLE ACCESS     BY LOCAL INDEX ROWID EMP          KEY(INLIST)     KEY(INLIST)
INDEX            RANGE SCAN           EMP_EMPNO    KEY(INLIST)     KEY(INLIST)

パーティションの開始キーおよび終了キーに対するKEY(INLIST)指定は、索引の開始キーおよび終了キーにINリスト述語が表示されることを指定します。

12.9.5.2 INリスト列が索引でありパーティション列である場合

empnoが索引付けされている列で、それがパーティション列でもある場合、計画にはパーティション操作の前にINLIST ITERATOR操作が含まれています。

OPERATION        OPTIONS              OBJECT_NAME PARTITION_START PARTITION_STOP
---------------- ------------         ----------- --------------- --------------
SELECT STATEMENT
INLIST ITERATOR
PARTITION RANGE  ITERATOR                         KEY(INLIST)     KEY(INLIST)
TABLE ACCESS     BY LOCAL INDEX ROWID EMP         KEY(INLIST)     KEY(INLIST)
INDEX            RANGE SCAN           EMP_EMPNO   KEY(INLIST)     KEY(INLIST)

12.9.5.3 INリスト列がパーティション列である場合

empnoがパーティション列で、索引が存在しない場合は、INLIST ITERATOR操作は割り当てられません。

OPERATION         OPTIONS        OBJECT_NAME   PARTITION_START   PARTITION_STOP
----------------  ------------   -----------   ---------------   --------------
SELECT STATEMENT
PARTITION RANGE   INLIST                       KEY(INLIST)       KEY(INLIST)
TABLE ACCESS      FULL           EMP           KEY(INLIST)       KEY(INLIST)

emp_empnoビットマップ索引である場合、計画は次のとおりです。

OPERATION          OPTIONS           OBJECT_NAME
----------------   ---------------   -------------- 
SELECT STATEMENT
INLIST ITERATOR
TABLE ACCESS       BY INDEX ROWID    EMP
BITMAP CONVERSION  TO ROWIDS
BITMAP INDEX       SINGLE VALUE      EMP_EMPNO

12.9.6 ドメイン索引およびEXPLAIN PLANの例

また、EXPLAIN PLANを使用して、ドメイン索引に対するユーザー定義のCPUおよびI/Oコストを導出できます。EXPLAIN PLANは、これらの統計をPLAN_TABLEOTHER列に表示します。

たとえば、resume列にドメイン索引emp_resumeを持つユーザー定義演算子CONTAINSが表empに存在し、emp_resumeの索引タイプが演算子CONTAINSをサポートしている場合に、次の問合せをします。次の問合せの計画をEXPLAINします。

SELECT * FROM emp WHERE CONTAINS(resume, 'Oracle') = 1 

次のような計画が表示されます。

OPERATION            OPTIONS      OBJECT_NAME     OTHER 
-----------------    -----------  ------------    ----------------
SELECT STATEMENT 
TABLE ACCESS         BY ROWID     EMP
DOMAIN INDEX                      EMP_RESUME      CPU: 300, I/O: 4

12.10 PLAN_TABLE列

EXPLAIN PLAN文に使用されるPLAN_TABLEには、表12-1に示す列があります。

表12-1 PLAN_TABLE列

説明

STATEMENT_ID

VARCHAR2(30)

EXPLAIN PLAN文で指定した、オプションのSTATEMENT_IDパラメータの値です。

PLAN_ID

NUMBER

データベース内の計画の一意の識別子です。

TIMESTAMP

DATE

EXPLAIN PLAN文が生成された日時です。

REMARKS

VARCHAR2(80)

実行計画の各ステップに関連付けるコメント(最大80バイト)です。この列は、問合せに使用されたのがアウトラインであるか、SQLプロファイルかを示します。

PLAN_TABLEの行に関するコメントを追加または変更する必要がある場合は、UPDATE文を使用してPLAN_TABLEの行を修正してください。

OPERATION

VARCHAR2(30)

このステップで実行された内部操作の名前です。文に対して生成された最初の行の列には、次の値の1つが含まれます。

  • DELETE STATEMENT

  • INSERT STATEMENT

  • SELECT STATEMENT

  • UPDATE STATEMENT

この列の値の詳細は、表12-3を参照してください。

OPTIONS

VARCHAR2(225)

OPERATION列に記述されている操作に関するバリエーションです。

この列の値の詳細は、表12-3を参照してください。

OBJECT_NODE

VARCHAR2(128)

オブジェクト(表名またはビュー名)を参照するために使用されたデータベース・リンクの名前です。パラレル実行を指定したローカル問合せの場合、この列は、処理からの出力をデータベースが使用する順序を説明します。

OBJECT_OWNER

VARCHAR2(30)

表または索引を含むスキーマを所有しているユーザーの名前です。

OBJECT_NAME

VARCHAR2(30)

表または索引の名前です。

OBJECT_ALIAS

VARCHAR2(65)

SQL文に含まれる表またはビューの一意の別名です。索引の場合は、基礎となる表のオブジェクトの別名です。

OBJECT_INSTANCE

NUMERIC

元の文に指定されているオブジェクトの位置に対応する順番を示す数値です。番号付けは、元の文テキストの左から右へ、外側から内側へと行われます。ビューを展開した場合、この数値は予測できません。

OBJECT_TYPE

VARCHAR2(30)

たとえば、索引に対するNON-UNIQUEのような、オブジェクトに関して説明を与える修飾子です。

OPTIMIZER

VARCHAR2(255)

オプティマイザの現行モードです。

SEARCH_COLUMNS

NUMBERIC

現在は使用されていません。

ID

NUMERIC

実行計画の各ステップに割り当てられた番号です。

PARENT_ID

NUMERIC

IDのステップの出力について処理を行う次の実行ステップのIDです。

DEPTH

NUMERIC

計画により表される行ソース・ツリー内の操作の深さです。この値を使用して、PLAN TABLEレポートの行をインデントできます。

POSITION

NUMERIC

最初の出力行の場合、この列はオプティマイザが見積った、文を実行するためのコストを示します。その他の行の場合は、同じ親の他の子に対応する相対位置を示します。

COST

NUMERIC

オプティマイザの問合せアプローチによって見積られた操作コストです。表アクセス操作のためのコストは判断されません。この列の値には、特定の単位はなく、単に実行計画のコストを比較するために使用される重み値を示します。この列の値は、CPU_COST列とIO_COST列のファンクションです。

CARDINALITY

NUMERIC

この操作によってアクセスされる行数の問合せ最適化アプローチによる見積りです。

BYTES

NUMERIC

この操作によってアクセスされるバイト数の問合せ最適化アプローチによる見積りです。

OTHER_TAG

VARCHAR2(255)

OTHER列の内容を記述します。値は次のとおりです。

  • SERIAL(空白): シリアル実行。現在のところ、この場合はSQLはOTHER列にロードされません。

  • SERIAL_FROM_REMOTE (S -> R): リモート・サイトでシリアル実行されます。

  • PARALLEL_FROM_SERIAL (S -> P): シリアル実行。ステップの出力は、パーティション化されるか、パラレル実行サーバーにブロードキャストされます。

  • PARALLEL_TO_SERIAL (P -> S): パラレル実行。ステップの出力は、シリアルQCプロセスに戻されます。

  • PARALLEL_TO_PARALLEL (P -> P): パラレル実行。ステップの出力は、パラレル実行サーバーの2番目のセットに再パーティション化されます。

  • PARALLEL_COMBINED_WITH_PARENT (PWP): パラレル実行。ステップの出力は、同じパラレル処理の次のステップに送られます。親へのプロセス間通信はありません。

  • PARALLEL_COMBINED_WITH_CHILD (PWC): パラレル実行。ステップの入力は、同じパラレル処理の前のステップから受け取ります。子からのプロセス間通信はありません。

PARTITION_START

VARCHAR2(255)

アクセスしたパーティションの範囲のパーティションを開始します。次のいずれかの値です。

nは、開始パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。

KEYは、開始パーティションが実行時にパーティション・キー値から識別されることを示します。

ROW REMOVE_LOCATIONは、実行時に、取得された各レコードの位置から開始パーティション(終了パーティションと同じ)が計算されることを示します。レコードの位置は、ユーザーまたはグローバル索引によって獲得されます。

INVALIDは、アクセスしたパーティションの範囲が空であることを意味します。

PARTITION_STOP

VARCHAR2(255)

アクセスされるパーティションの範囲の停止パーティション。次のいずれかの値です。

nは、終了パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。

KEYは、終了パーティションが実行時にパーティション・キー値から識別されることを示します。

ROW REMOVE_LOCATIONは、実行時に、取得された各レコードの位置から終了パーティション(開始パーティションと同じ)が計算されることを示します。レコードの位置は、ユーザーまたはグローバル索引によって獲得されます。

INVALIDは、アクセスしたパーティションの範囲が空であることを意味します。

PARTITION_ID

NUMERIC

PARTITION_STARTPARTITION_STOP列の値の対を計算したステップです。

OTHER

LONG

ユーザーにとって有効な実行ステップに関するその他の情報です。OTHER_TAG列を参照してください。

DISTRIBUTION

VARCHAR2(30)

プロデューサ問合せサーバーからコンシューマ問合せサーバーへ行を分配する方法です。

この列に使用可能な値の詳細は、表12-2を参照してください。コンシューマ問合せサーバーおよびプロデューサ問合せサーバーの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください。

CPU_COST

NUMERIC

問合せオプティマイザのアプローチによって見積られた操作のCPUコストです。この列の値は、操作に必要なマシン・サイクル数に比例します。ルールベース・アプローチを使用する文では、この列はNULLになります。

IO_COST

NUMERIC

問合せオプティマイザのアプローチによって見積られた操作のI/Oコストです。この列の値は、操作で読み取られるデータ・ブロックの数に比例します。ルールベース・アプローチを使用する文では、この列はNULLになります。

TEMP_SPACE

NUMERIC

問合せオプティマイザのアプローチで見積られた、操作で使用される一時領域をバイト単位で表したものです。ルールベース・アプローチを使用する文の場合、または一時領域を使用しない操作の場合、この列はNULLです。

ACCESS_PREDICATES

VARCHAR2(4000)

アクセス構造の行を特定する場合に使用する述語です。たとえば、索引レンジ・スキャンの開始や停止の述語などがあります。

FILTER_PREDICATES

VARCHAR2(4000)

フィルタにかけた後で行を生成する場合に使用する述語です。

PROJECTION

VARCHAR2(4000)

操作によって生成される式です。

TIME

NUMBER(20,2)

問合せの最適化によって見積られた操作の秒単位の経過時間です。ルールベース・アプローチを使用する文では、この列はNULLになります。

QBLOCK_NAME

VARCHAR2(30)

問合せブロックの名前です。システム生成またはQB_NAMEヒントによるユーザー定義のいずれかとなります。


表12-2で、DISTRIBUTION列に使用される値を説明します。

表12-2 PLAN_TABLEのDISTRIBUTION列の値

DISTRIBUTIONテキスト 説明

PARTITION (ROWID)

UPDATEまたはDELETEを実行する行のROWIDを使用し、表または索引のパーティション化に基づいて行を問合せサーバーにマップします。

PARTITION (KEY)

列のセットを使用し、表または索引のパーティション化に基づいて行を問合せサーバーにマップします。パーシャル・パーティション・ワイズ結合、PARALLEL INSERT、パーティション表のCREATE TABLE AS SELECTおよびCREATE PARTITIONED GLOBAL INDEXに使用します。

HASH

結合キーについて、ハッシュ関数を使用して、行を問合せサーバーにマップします。PARALLEL JOINまたはPARALLEL GROUP BYに使用します。

RANGE

ソート・キーの範囲を使用して、行を問合せサーバーにマップします。文にORDER BY句がある場合に使用します。

ROUND-ROBIN

行を問合せサーバーにランダムにマップします。

BROADCAST

表全体の行を各問合せサーバーにブロードキャストします。ある表がその他の表に比べて非常に小さい場合、パラレル結合に使用します。

QC (ORDER)

QCは、最初の問合せサーバーから最後の問合せサーバーまで順番に入力データを受け取ります。文にORDER BY句がある場合に使用します。

QC (RANDOM)

QCは、入力をランダムに受け取ります。文にORDER BY句がない場合に使用します。


表12-3に、EXPLAIN PLAN文によって生成されるOPERATIONOPTIONSの各組合せおよびその実行計画におけるそれぞれの意味を示します。

表12-3 EXPLAIN PLANによって生成されるOPERATION値とOPTIONS値

操作 オプション 説明

AND-EQUAL


複数のROWIDのセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。この処理は単一列索引のアクセス・パスに対して使用されます。

BITMAP

CONVERSION

TO ROWIDSは、ビットマップ表現を、表にアクセスするために使用できる実際のROWIDに変換します。

FROM ROWIDSは、ROWIDをビットマップ表現に変換します。

COUNTは、実際の値を必要としない場合にROWIDの数を戻します。

BITMAP

INDEX

SINGLE VALUEは、索引内の単一のキー値のビットマップを参照します。

RANGE SCANは、ある範囲のキー値のビットマップを取り出します。

FULL SCANは、開始キーまたは終了キーがない場合にビットマップ索引の全体スキャンを実行します。

BITMAP

MERGE

レンジ・スキャンの結果の複数のビットマップを1つのビットマップにマージします。

BITMAP

MINUS

片方のビットマップのビットを、もう一方のビットマップから減算します。行ソースは否定述語に対して使用されます。減算が発生する可能性があるビットマップを作成する非否定述語がある場合にのみ使用できます。「EXPLAIN PLANによるビットマップ索引の表示」で例を示します。

BITMAP

OR

2つのビットマップのビット単位のORを計算します。

BITMAP

AND

2つのビットマップのビット単位のANDを計算します。

BITMAP

KEY ITERATION

表の行ソースから各行を取り出し、ビットマップ索引から対応するビットマップを検索します。その後、このビットマップのセットは、次のBITMAP MERGE操作で1つのビットマップにマージされます。

CONNECT BY

CONNECT BY句を含んでいる問合せについて階層順に行を取り出します。

CONCATENATION

複数の行のセットを受け取り、そのセットのUNION-ALLを戻す処理。

COUNT

表から選択された行の数をカウントする処理。

COUNT

STOPKEY

戻される行数をWHERE句のROWNUM式によって制限するカウント処理。

CUBE SCAN

すべてのキューブ・アクセスで内部結合を使用します。

CUBE SCAN

PARTIAL OUTER

少なくとも1つのディメンションで外部結合を使用し、その他のディメンションで内部結合を使用します。

CUBE SCAN

OUTER

すべてのキューブ・アクセスで外部結合を使用します。

DOMAIN INDEX

ドメイン索引からの1つ以上のROWIDの取出し。オプション列には、ユーザー定義ドメイン・インデックス・コスト関数から与えられた情報が含まれています。

FILTER

行のセットを受け取り、そのいくつかを取り除き、残りを戻す処理。

FIRST ROW

問合せで選択される最初の行のみの取出し。

FOR UPDATE

FOR UPDATE句が含まれている問合せによって選択される行を取り出し、ロックする処理。

HASH

GROUP BY

GROUP BY句を持つ問合せで、行のセットを複数のグループにハッシュする処理。

HASH

GROUP BY PIVOT

GROUP BY句を持つ問合せで、行のセットを複数のグループにハッシュする処理。PIVOT操作は、HASH GROUP BY演算子のピボット固有の最適化を示します。

HASH JOIN

(これらは結合操作です。)

2つのセットの行を結合し、結果を戻す操作。この結合方法は、データのラージ・データ・セット(DSSやバッチなど)の結合に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。

問合せオプティマイザは、2つの表またはデータ・ソースの小さいほうを使用して、メモリー内に結合キーについてのハッシュ表を作成します。次に、大きいほうの表をスキャンし、ハッシュ表を調べて結合された行を見つけます。

HASH JOIN

ANTI

ハッシュ(左側)アンチ結合。

HASH JOIN

SEMI

ハッシュ(左側)セミ結合。

HASH JOIN

RIGHT ANTI

ハッシュ右側アンチ結合。

HASH JOIN

RIGHT SEMI

ハッシュ右側セミ結合。

HASH JOIN

OUTER

ハッシュ(左側)外部結合。

HASH JOIN

RIGHT OUTER

ハッシュ(右側)外部結合。

INDEX

(これらはアクセス方法です。)

UNIQUE SCAN

索引からの単一のROWIDの取出し。

INDEX

RANGE SCAN

索引からの1つ以上のROWIDの取出し。索引値は昇順でスキャンされます。

INDEX

RANGE SCAN DESCENDING

索引からの1つ以上のROWIDの取出し。索引値は降順でスキャンされます。

INDEX

FULL SCAN

スタート・キーおよびストップ・キーがない場合の、索引からのすべてのROWIDの取得。索引値は昇順でスキャンされます。

INDEX

FULL SCAN DESCENDING

スタート・キーおよびストップ・キーがない場合の、索引からのすべてのROWIDの取得。索引値は降順でスキャンされます。

INDEX

FAST FULL SCAN

マルチブロックREADを使用した全ROWID(および列の値)の取得。ソート順は定義できません。索引付けされた列に対してのみ、全表スキャンと比較されます。コストベース・オプティマイザでのみ使用可能です。

INDEX

SKIP SCAN

索引内の先頭列を使用しない、連結索引からのROWIDの取得。コストベース・オプティマイザでのみ使用可能です。

INLIST ITERATOR

INリスト述語内の各値に対して、計画内の次の操作を反復します。

INTERSECTION

2つの行のセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。

MERGE JOIN

(これらは結合操作です。)

2つの行のセットを受け取り、それぞれを特定の値でソートし、一方のセットの各行を他方の行と突き合せて結合し、その結果を戻す処理。

MERGE JOIN

OUTER

外部結合文を実行するマージ結合処理。

MERGE JOIN

ANTI

マージ・アンチ結合。

MERGE JOIN

SEMI

マージ・セミ結合。

MERGE JOIN

CARTESIAN

文中に他の表への結合条件を持たない1つ以上の表について発生する操作です。結合とともに発生する可能性がありますが、計画内ではCARTESIANとフラグが付かないことがあります。

CONNECT BY

CONNECT BY句を含んでいる問合せに対する、階層順での行の取出し。

MAT_VIEW REWITE ACCESS

(これらはアクセス方法です。)

FULL

マテリアライズド・ビューのすべての行の取出し。

MAT_VIEW REWITE ACCESS

SAMPLE

マテリアライズド・ビューのサンプル行の取出し。

MAT_VIEW REWITE ACCESS

CLUSTER

索引クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。

MAT_VIEW REWITE ACCESS

HASH

ハッシュ・クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。

MAT_VIEW REWITE ACCESS

BY ROWID RANGE

ROWID範囲に基づいたマテリアライズド・ビューからの行の取出し。

MAT_VIEW REWITE ACCESS

SAMPLE BY ROWID RANGE

ROWID範囲に基づいたマテリアライズド・ビューからのサンプル行の取出し。

MAT_VIEW REWITE ACCESS

BY USER ROWID

ユーザー指定のROWIDを使用してマテリアライズド・ビューの行が指定される場合。

MAT_VIEW REWITE ACCESS

BY INDEX ROWID

マテリアライズド・ビューがパーティション化されておらず、索引を使用して行が指定される場合。

MAT_VIEW REWITE ACCESS

BY GLOBAL INDEX ROWID

マテリアライズド・ビューがパーティション化されており、グローバル索引のみを使用して行が指定される場合。

MAT_VIEW REWITE ACCESS

BY LOCAL INDEX ROWID

マテリアライズド・ビューがパーティション化されており、1つ以上のローカル索引と、場合によってはいくつかのグローバル索引を使用して行が指定される場合。

パーティション区間:

パーティション区間は次のようにして計算されている可能性があります。

前のPARTITIONステップによって決定される場合。この場合、PARTITION_START列の値とPARTITION_STOP列の値はPARTITIONステップ内の値をレプリケートし、PARTITION_IDにはPARTITIONステップのIDが組み込まれます。PARTITION_STARTおよびPARTITION_STOPに使用できる値は、NUMBER(n)、KEYINVALIDです。

MAT_VIEW REWRITE ACCESSまたはINDEXステップ自体で決定される場合。この場合、PARTITION_IDにはそのステップのIDが組み込まれます。PARTITION_STARTおよびPARTITION_STOPに使用できる値は、NUMBER(n)、KEYROW REMOVE_LOCATION(MAT_VIEW REWRITE ACCESSのみ)およびINVALIDです。

MINUS

2つの行のセットを受け取り、最初のセットにあって2番目のセットにない行を戻して、重複をなくす処理。

NESTED LOOPS

(これらは結合操作です。)

外側のセットと内側のセット、2つの行のセットを受け取る処理。Oracle Databaseは、外側のセットの各行を内側のセットの各行と比較し、条件を満たす行を戻します。この結合方法は、小さいサブセットのデータを結合する場合(OLTP)に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。

NESTED LOOPS

OUTER

外部結合文を実行するネステッド・ループ操作。

PARTITION

PARTITION_START列およびPARTITION_STOP列によって指定された範囲の各パーティションに対して、計画内の次の操作を反復します。PARTITIONは、単一のパーティション・オブジェクト(表または索引)や同じ数でパーティション化されたオブジェクトのセット(パーティション表やそのローカル索引)に適用できるパーティションの区間を示します。パーティションの区間は、PARTITIONPARTITION_STARTおよびPARTITION_STOPの値で指定されます。パーティションの開始および終了の有効な値は、表12-1を参照してください。

PARTITION

SINGLE

1つのパーティションへのアクセス。

PARTITION

ITERATOR

多数のパーティション(サブセット)へのアクセス。

PARTITION

ALL

すべてのパーティションへのアクセス。

PARTITION

INLIST

INリスト述語を基準にしたイテレータに類似するもの。

PARTITION

INVALID

アクセスするよう設定されているパーティションが空であることを示します。

PX ITERATOR

BLOCKCHUNK

パラレル・スレーブ・セット間でのブロックまたはチャンク範囲へのオブジェクトの分割を実装します。

PX COORDINATOR

パラレル問合せスレーブを使用して下位のパラレル計画を制御、スケジュールおよび実行する問合せコーディネータを実装します。また、パラレルに実行され、常に下位にPX SEND QC操作を持つ計画部分の終わりとして、シリアライズ・ポイントを表します。

PX PARTITION

セマンティクスは通常のPARTITION操作と同じですが、パラレル計画に表示されます。

PX RECEIVE

PX SENDノード上で実行される送信側/プロデューサ(QCまたはスレーブ)からパーティション化されたデータを読み取る、コンシューマ/受信側スレーブ・ノードを示します。以前は、この情報はDISTRIBUTION列に表示されていました。表12-2を参照してください。

PX SEND

QC (RANDOM)HASHRANGE

スレーブの2つのパラレル・セットの間における配分方法を実装します。2つのスレーブ・セット間の境界と、送信側/プロデューサ側(QCまたはスレーブ)でのデータのパーティション化方法を示します。以前は、この情報はDISTRIBUTION列に表示されていました。表12-2を参照してください。

REMOTE

リモート・データベースからのデータの取出し。

SEQUENCE

順序値のアクセスを伴う処理。

SORT

AGGREGATE

選択した行のグループにグループ関数を適用した結果として取得される単一行の取出し。

SORT

UNIQUE

行のセットをソートし、重複をなくす処理。

SORT

GROUP BY

GROUP BY句を持つ問合せで、行のセットを複数のグループにソートする処理。

SORT

GROUP BY PIVOT

GROUP BY句を持つ問合せで、行のセットを複数のグループにソートする処理。PIVOT操作は、SORT GROUP BY演算子のピボット固有の最適化を示します。

SORT

JOIN

マージ結合の前に、一連の行をソートする操作。

SORT

ORDER BY

ORDER BY句を持つ問合せに対して行のセットをソートする処理。

TABLE ACCESS

(これらはアクセス方法です。)

FULL

表のすべての行の取出し。

TABLE ACCESS

SAMPLE

表のサンプル取得された行の取出し。

TABLE ACCESS

CLUSTER

索引クラスタのキーの値に基づいた、表からの行の取出し。

TABLE ACCESS

HASH

ハッシュ・クラスタのキーの値に基づいた、表からの行の取出し。

TABLE ACCESS

BY ROWID RANGE

ROWID範囲に基づいた表からの行の取出し。

TABLE ACCESS

SAMPLE BY ROWID RANGE

ROWID範囲に基づいた表からのサンプル行の取出し。

TABLE ACCESS

BY USER ROWID

ユーザー指定のROWIDを使用して表の行が指定される場合。

TABLE ACCESS

BY INDEX ROWID

表がパーティション化されておらず、索引を使用して行が指定される場合。

TABLE ACCESS

BY GLOBAL INDEX ROWID

表がパーティション化されており、グローバル索引のみを使用して行が指定される場合。

TABLE ACCESS

BY LOCAL INDEX ROWID

表がパーティション化されており、1つ以上のローカル索引と場合によってはいくつかのグローバル索引を使用して、行が指定される場合。

パーティション区間:

パーティション区間は次のようにして計算されている可能性があります。

前のPARTITIONステップによって決定される場合。この場合、PARTITION_START列の値とPARTITION_STOP列の値はPARTITIONステップ内の値をレプリケートし、PARTITION_IDにはPARTITIONステップのIDが組み込まれます。PARTITION_STARTおよびPARTITION_STOPに使用できる値は、NUMBER(n)、KEYINVALIDです。

TABLE ACCESSまたはINDEXステップ自体で決定される場合。この場合、PARTITION_IDにはそのステップのIDが組み込まれます。PARTITION_STARTおよびPARTITION_STOPに使用できる値は、NUMBER(n)、KEYROW REMOVE_LOCATION(TABLE ACCESSのみ)およびINVALIDです。

TRANSPOSE

GROUP BYの結果を入れ換えて最終的にピボットされたデータを生成するPIVOT操作を評価する操作。

UNION

2つの行のセットを受け取り、重複をなくして、そのセットの連結結果を戻す処理。

UNPIVOT

列から行にデータを回転させる操作。

VIEW

ビューの問合せを実行し、結果の行を別の処理に戻す処理。



関連項目:

PLAN_TABLEの詳細は、『Oracle Databaseリファレンス』を参照してください。