ヘッダーをスキップ
Oracle Databaseパフォーマンス・チューニング・ガイド
11gリリース1(11.1)
E05743-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

12 EXPLAIN PLANの使用方法

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

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

12.1 EXPLAIN PLANについて

EXPLAIN PLAN文は、SELECTUPDATEINSERTおよびDELETE文についてOracleオプティマイザが選択した実行計画を表示します。文の実行計画とは、Oracleがその文を実行するために行う一連の処理です。

行ソース・ツリーは、実行計画の中核です。行ソース・ツリーは次の情報を示します。

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

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


注意:

Oracle Performance ManagerチャートとOracle SQL Analyzeは、EXPLAIN PLANを自動的に作成して表示できます。EXPLAIN PLANの使用方法の詳細は、『Oracle Enterprise Manager概要』を参照してください。

12.1.1 実行計画の変化理由

問合せオプティマイザを使用すると、実行計画は基礎となるオプティマイザ入力が変化するたびに変化します。EXPLAIN PLANの出力は、SQL文の説明段階での実行方法を示します。この方法は、実行環境とEXPLAIN PLAN環境との違いにより、SQL文の実際の実行計画とは異なる場合があります。


注意:

実行計画の変更から生じる可能性があるSQLパフォーマンスの低下を回避するには、SQL計画の管理を使用することを検討してください。詳細は、第15章「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には、カーソル・キャッシュに格納されている各文の実行計画が含まれます。その定義は、PLAN_TABLEに類似しています。「PLAN_TABLE列」を参照してください。

EXPLAIN PLANとは異なり、V$SQL_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の制限事項

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

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

12.2 PLAN_TABLE出力表

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

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

たとえば、SQL*Plusセッションで例12-2のコマンドを実行し、HRスキーマにPLAN_TABLEを作成します。

例12-2 PLAN_TABLEの作成

CONNECT HR/your_password
@$ORACLE_HOME/rdbms/admin/utlxplan.sql

Table created.

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

別の名前の出力表が必要な場合は、最初にutlxplan.sqlスクリプトを使用して手動でPLAN_TABLEを作成してから、RENAME SQL文で表の名前を変更します。たとえば、次のようにします。

RENAME PLAN_TABLE TO my_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-3の場合は、st1が文の識別子として指定されています。

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

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

12.3.2 EXPLAIN PLANでの別の表の指定

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

例12-4 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出力を表示します。

12.4.1 PLAN_TABLE出力のカスタマイズ

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

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

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

  • 疑似列LEVELCONNECT 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-5の文は、実行計画の表示に使用されます。

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

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

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

例12-6 文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は、全表スキャンでアクセスされます。

例12-7 文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文の実行を示します。

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

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

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

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

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

パラレル・ステップによって多数の行が生成されると、問合せコーディネータ(QC)がそれらの行を生成後すぐに処理できない場合があります。このような状況を改善する方法はありません。


関連項目:

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

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

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

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

例12-8 パラレル問合せの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-9の問合せおよび計画の例を検討します。

例12-9 ビットマップ検索による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オプションは、表アクセスに必要なROWIDを生成するのに使用されます。


注意:

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

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演算子はそのCacheIdb06ppfz9pxzstbttpbqyqnfbmy)によって識別されます。このCacheIdを使用して、V$RESULT_CACHE_OBJECTSビューに対して問合せを実行できます。

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

EXPLAIN PLANを使用すると、特定の問合せでのパーティション・オブジェクトにOracleがアクセスする方法を参照できます。

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

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

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

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

hire_dateで範囲ごとにパーティション化されている次のemp_range表を参考に、プルーニングの表示方法を例示します。Oracleサンプル・スキーマの表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 |
--------------------------------------------------------------------------------------

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

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

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であることを除き、Oracleはハッシュ・パーティション・オブジェクトに対して同じ情報を表示します。また、ハッシュ・パーティション化では、プルーニングが可能なのは等価述語かINリスト述語を使用している場合のみです。

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

Oracleがコンポジット・パーティション・オブジェクトのプルーニング情報を表示する方法を例示するために、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がコンポジット・パーティション・オブジェクトの全パーティションの全サブパーティションにアクセスする場合の計画を示します。そのために、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が各パーティション内でアクセスするサブパーティションは1つのみなので、その行ソースのオプションはSINGLEです。PARTITION_STARTおよびPARTITION_STOPKEYに設定されます。これは、Oracleがサブパーティションの番号を実行時に判別することを意味します。

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

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

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

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表がパーティション化されていないことにより、パーシャル・パーティション・ワイズ結合が使用可能になります。Oracleは結合前にdept2表を動的にパーティション化します。

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

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-10および例12-11では、問合せオプティマイザがこの問合せのコストに基づいて異なる計画を選択する可能性があるため、パーシャル・パーティション・ワイズ結合を明示的に強制するために、PQ_DISTRIBUTEヒントが使用されていることに注意してください。

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

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

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

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

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)

PARTITION_START列とPARTITION_STOP列に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をサポートしている場合に、次の問合せをします。

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の取得。Oracle9iで導入されています。コストベース・オプティマイザでのみ使用可能です。

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_LOCATIONMAT_VIEW REWRITE ACCESSのみ)およびINVALIDです。

MINUS

.

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

NESTED LOOPS

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

.

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

NESTED LOOPS

OUTER

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

PARTITION

.

PARTITION_START列およびPARTITION_STOP列によって指定された範囲の各パーティションに対して、計画内の次の操作を反復します。PARTITIONは、単一のパーティション・オブジェクト(表または索引)や同じ数でパーティション化されたオブジェクトのセット(パーティション表やそのローカル索引)に適用できるパーティションの区間を示します。パーティションの区間は、PARTITIONPARTITION_STARTおよびPARTITION_STOPの値で指定されます。PARTITION_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_LOCATIONTABLE ACCESSのみ)およびINVALIDです。

TRANSPOSE

.

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

UNION

.

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

UNPIVOT

.

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

VIEW

.

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



関連項目:

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