日本語PDF

EXPLAIN PLAN

目的

EXPLAIN PLAN文を使用すると、指定したSQL文を実行するためにOracle Databaseが使用する実行計画を決定できます。この文によって、実行計画の各ステップを記述している行が、指定した表に挿入されます。SQLトレース機能の一部としてEXPLAIN PLAN文を発行することもできます。

この文によって、文を実行するコストも決まります。表にドメイン索引が定義されている場合、ユーザー定義のCPUおよびI/Oコストが挿入されます。

配布メディアのSQLスクリプトの中に、サンプル出力表PLAN_TABLEの定義があります。使用する出力表は、列の名前およびデータ型がこのサンプル表と同じである必要があります。このスクリプトの一般的な名前は、UTLXPLAN.SQLです。正確な名前および位置は、使用するオペレーティング・システムによって異なります。

キャッシュされたカーソルに関する情報は、次の動的パフォーマンス・ビューから得られます。

  • SQLカーソルが使用する作業領域の詳細は、V$SQL_WORKAREAを問い合せます。

  • キャッシュされたカーソルの実行計画の詳細は、V$SQL_PLANを問い合せます。

  • キャッシュされたカーソルの各ステップでの実行統計または実行計画の操作(生成された行数、読み取られたブロック数など)は、V$SQL_PLAN_STATISTICSを問い合せます。

  • 前述の3つのビューの処理結果を1つにまとめた情報を取得する場合は、V$SQL_PLAN_STATISTICS_ALLを問い合せます。

  • この文の実行が監視されている場合、キャッシュされたカーソルの実行計画の各ステップまたは各操作での実行統計は、V$SQL_PLAN_MONITORに表示されます。MONITORヒントを使用すると、監視を強制的に適用できます。

関連項目:

前提条件

EXPLAIN PLAN文を実行する場合、実行計画を格納する既存の出力表に行を挿入するための権限が必要です。

出力する実行計画の適用対象であるSQL文を実行するための権限も必要です。このSQL文でビューにアクセスする場合は、このビューの基礎になっているすべての表およびビューへのアクセス権限が必要です。このビューが別のビューに基づき、さらにこの別のビューが、ある表に基づいている場合、別のビューとそのビューの基礎になっている表へのアクセス権限が必要です。

EXPLAIN PLANで作成された実行計画を検証する場合は、出力表へ問い合せる権限が必要です。

EXPLAIN PLAN文はデータ操作言語(DML)文であり、データ定義言語(DDL)文ではありません。そのため、EXPLAIN PLAN文で加えられた変更内容は暗黙的にコミットされません。出力表のEXPLAIN PLAN文で生成された行を保存する場合は、この文を指定したトランザクションをコミットする必要があります。

関連項目:

計画表の移入および問合せに必要な権限の詳細は、「INSERT」および「SELECT」を参照してください。

構文

セマンティクス

SET STATEMENT_ID句

実行計画が出力される表の中で、この実行計画に該当する行にあるSTATEMENT_ID列の値を指定します。この値によって、実行計画の行を出力表の中の他の行と区別できます。ユーザーの出力表に多数の実行計画の行が含まれている場合は、必ず、STATEMENT_IDの値を指定します。この句を省略した場合、デフォルトでSTATEMENT_ID値がNULLに設定されます。

INTO table

出力表の名前を指定し、オプションとしてそのスキーマおよびデータベースの名前も指定します。この表は、EXPLAIN PLAN文を使用する前に作成しておく必要があります。

schemaを指定しない場合、表は自分のスキーマ内にあるとみなされます。

dblinkには、出力表が格納されているリモートのOracle Databaseに対するデータベース・リンクの完全な名前または名前の一部を指定します。Oracle Databaseの分散機能を使用している場合にのみ、リモート出力表を指定できます。dblinkを省略した場合、表がローカル・データベース上にあるとみなされます。データベース・リンクの参照方法の詳細は、「リモート・データベース内のオブジェクトの参照」を参照してください。

INTO句を省略した場合、出力表は、ローカル・データベース上の自分のスキーマ内にあるPLAN_TABLEであるとみなされます。

FOR statement

実行計画生成の対象となるSELECTINSERTUPDATEDELETEMERGECREATE TABLECREATE INDEXまたはALTER INDEX ... REBUILD文を指定します。

EXPLAIN PLANのノート

EXPLAIN PLANには、次のノートがあります。

  • statementparallel_clauseを指定した場合、結果として生成される実行計画はパラレルで実行されます。ただし、EXPLAIN PLANコマンドによって計画表に実際に文が挿入されるため、ユーザーが発行したパラレルDML文は、トランザクションの最初のDML文ではなくなります。これは、トランザクション1つにつきパラレルDML文は1つというOracle Databaseの制限に違反するため、この文はシリアルで実行されます。文をパラレルで実行するには、EXPLAIN PLAN文をコミットまたはロールバックしてから、パラレルDML文を発行する必要があります。

  • 一時表上で操作するための実行計画を判断する場合、EXPLAIN PLANは、同一セッションから実行する必要があります。これは、一時表内のデータがセッション固有であるためです。

EXPLAIN PLANの例

次の文は、UPDATE文の実行計画およびコストを決定し、実行計画を記述した行をSTATEMENT_ID値'Raise in Tokyo'とともに、指定したplan_table表に挿入します。

EXPLAIN PLAN 
    SET STATEMENT_ID = 'Raise in Tokyo' 
    INTO plan_table 
    FOR UPDATE employees 
        SET salary = salary * 1.10 
        WHERE department_id =  
           (SELECT department_id FROM departments
               WHERE location_id = 1700); 

次のSELECT文は、plan_table表への問合せを実行し、実行計画およびコストを戻します。

SELECT id, LPAD(' ',2*(LEVEL-1))||operation operation, options,
       object_name, object_alias, position 
    FROM plan_table 
    START WITH id = 0 AND statement_id = 'Raise in Tokyo'
    CONNECT BY PRIOR id = parent_id AND statement_id = 'Raise in Tokyo'
    ORDER BY id;

問合せによって、次の実行計画が戻されます。

 ID OPERATION            OPTIONS              OBJECT_NAME          OBJECT_ALIAS         POSITION
--- -------------------- -------------------- -------------------- -------------------- --------
  0 UPDATE STATEMENT                                                                           4
  1   UPDATE                                  EMPLOYEES                                        1
  2     INDEX            RANGE SCAN           EMP_DEPARTMENT_IX    EMPLOYEES@UPD$1             1
  3       TABLE ACCESS   BY INDEX ROWID       DEPARTMENTS          DEPARTMENTS@SEL$1           1
  4         INDEX        RANGE SCAN           DEPT_LOCATION_IX     DEPARTMENTS@SEL$1           1

POSITION列の1行目の値は、文のコストが4であることを示しています。

EXPLAIN PLAN: パーティション化された例

サンプル表sh.salesは、time_id列でパーティション化されます。パーティションsales_q3_2000には、2000年10月1日より小さい時刻の値があり、time_id列にローカル索引sales_time_bixがあります。

次の問合せについて考えてみます。

EXPLAIN PLAN FOR
  SELECT * FROM sales 
     WHERE time_id BETWEEN :h AND '01-OCT-2000';

ここで、:hはすでに宣言されているバインド変数を指します。EXPLAIN PLAN文は、PLAN_TABLEを出力表とする次の問合せを実行します。次の問合せによって、パーティション情報などの基本的な実行計画が得られます。

SELECT operation, options, partition_start, partition_stop,
       partition_id
  FROM plan_table;