この章の内容は次のとおりです。
この項では、EXPLAIN PLANの例を使用して実行計画を説明します。次の問合せで実行計画が表示されます。
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'statement_id','BASIC'));
例7-1 文ID ex_plan1のEXPLAIN PLAN
次の計画は、SELECT文の実行を示します。表employeesは、全表スキャンでアクセスされます。表employeesのすべての行がアクセスされ、各行がWHERE句の条件に基づいて評価されます。
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 | ---------------------------------------
例7-2 文ID ex_plan2のEXPLAIN PLAN
この計画は、SELECT文の実行を示します。この例では、データベース・レンジは、EMP_NAME_IX索引をスキャンして、WHERE句の基準を評価します。
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 | ----------------------------------------
この項の内容は次のとおりです。
適応オプティマイザは、実行時の統計に基づいて計画を適応させることを可能にするオプティマイザの機能です。すべての適応メカニズムでは、デフォルトの計画とは異なる、文の最終計画を実行できます。
適応問合せ計画は、現在の文の実行中にサブプランの中から選択されます。対照的に、自動再最適化では、現在の文の実行後に行われる自動再最適化の実行時にのみ計画が変更されます。
計画のNotesセクションのコメントに基づいて、データベースでSQL文の適応問合せ最適化が使用されたかどうかを判断できます。コメントには、行ソースが動的かどうか、または自動再最適化が計画に適用されたかどうかが示されます。
前提条件
このチュートリアルでは、次のことが前提となっています。
STATISTICS_LEVEL初期化パラメータがALLに設定されています。
データベースでは、適応実行にデフォルト設定が使用されています。
ユーザーoeとして、次の別々の問合せを発行します。
SELECT o.order_id, v.product_name
FROM orders o,
( SELECT order_id, product_name
FROM order_items o, product_information p
WHERE p.product_id = o.product_id
AND list_price < 50
AND min_price < 40 ) v
WHERE o.order_id = v.order_id
SELECT product_name
FROM order_items o, product_information p
WHERE o.unit_price = 15
AND quantity > 1
AND p.product_id = o.product_id
各問合せを実行する前に、DBMS_XPLAN.DISPLAY_PLANを問い合せてデフォルトの計画(つまり、適応メカニズムを適用する前にオプティマイザによって選択される計画)を確認します。
各問合せの実行後、DBMS_XPLAN.DISPLAY_CURSORを問い合せて最終計画と適応問合せ計画を確認します。
SYSにより、oeに次の権限が付与されています。
GRANT SELECT ON V_$SESSION TO oe
GRANT SELECT ON V_$SQL TO oe
GRANT SELECT ON V_$SQL_PLAN TO oe
GRANT SELECT ON V_$SQL_PLAN_STATISTICS_ALL TO oe
適応最適化の結果を確認する手順は次のとおりです。
SQL*Plusを起動し、データベースにユーザーoeとして接続します。
ordersを問い合せます。
たとえば、次の文を使用します。
SELECT o.order_id, v.product_name
FROM orders o,
( SELECT order_id, product_name
FROM order_items o, product_information p
WHERE p.product_id = o.product_id
AND list_price < 50
AND min_price < 40 ) v
WHERE o.order_id = v.order_id;
カーソル内に計画を表示します。
たとえば、次のコマンドを実行します。
SET LINESIZE 165 SET PAGESIZE 0 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'+ALLSTATS'));
次のサンプル出力はページに収まるようにあらかじめ折り返されています。この計画では、オプティマイザは、ネステッド・ループ結合を選択します。元のオプティマイザの見積りは、E-Rows列に示されています。一方、実行中に収集された実際の統計は、A-Rows列に示されています。MERGE JOIN操作では、見積られた行数と実際の行数の差異は大きなものになります。
-------------------------------------------------------------------------------------------- |Id| Operation | Name |Start|E-Rows|A-Rows|A-Time|Buff|OMem|1Mem|O/1/M| -------------------------------------------------------------------------------------------- | 0| SELECT STATEMENT | | 1| | 269|00:00:00.09|1338| | | | | 1| NESTED LOOPS | | 1| 1| 269|00:00:00.09|1338| | | | | 2| MERGE JOIN CARTESIAN| | 1| 4|9135|00:00:00.03| 33| | | | |*3| TABLE ACCESS FULL |PRODUCT_INFORMAT| 1| 1| 87|00:00:00.01| 32| | | | | 4| BUFFER SORT | | 87|105|9135|00:00:00.01| 1|4096|4096|1/0/0| | 5| INDEX FULL SCAN | ORDER_PK | 1|105| 105|00:00:00.01| 1| | | | |*6| INDEX UNIQUE SCAN | ORDER_ITEMS_UK |9135| 1| 269|00:00:00.03|1305| | | | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - filter(("MIN_PRICE"<40 AND "LIST_PRICE"<50)) 6 - access("O"."ORDER_ID"="ORDER_ID" AND "P"."PRODUCT_ID"="O"."PRODUCT_ID")
手順2で実行したものと同じordersの問合せを実行します。
手順3で実行したものと同じSELECT文を使用して、カーソル内に実行計画を表示します。
次の例は、オプティマイザがハッシュ結合を使用する別の計画を選択したことを示しています。Noteセクションには、オプティマイザが統計フィードバックを使用して、問合せの2回目の実行に対するコストの見積りを調整したことが示されています。これは自動再最適化のよい例です。
-------------------------------------------------------------------------------------------- |Id| Operation |Name |Start|E-Rows|A-Rows|A-Time|Buff|Reads|OMem|1Mem|O/1/M| -------------------------------------------------------------------------------------------- | 0| SELECT STATEMENT | | 1 | |269|00:00:00.02|60|1| | | | | 1| NESTED LOOPS | | 1 |269|269|00:00:00.02|60|1| | | | |*2| HASH JOIN | | 1 |313|269|00:00:00.02|39|1|1000K|1000K|1/0/0| |*3| TABLE ACCESS FULL |PRODUCT_INFORMA| 1 | 87| 87|00:00:00.01|15|0| | | | | 4| INDEX FAST FULL SCAN|ORDER_ITEMS_UK | 1 |665|665|00:00:00.01|24|1| | | | |*5| INDEX UNIQUE SCAN |ORDER_PK |269| 1|269|00:00:00.01|21|0| | | | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID") 3 - filter(("MIN_PRICE"<40 AND "LIST_PRICE"<50)) 5 - access("O"."ORDER_ID"="ORDER_ID") Note ----- - statistics feedback used for this statement
V$SQLを問い合せて、パフォーマンスが改善されていることを確認します。
次の問合せは、2つの文のパフォーマンスを示しています(出力例も示します)。
SELECT CHILD_NUMBER, CPU_TIME, ELAPSED_TIME, BUFFER_GETS
FROM V$SQL
WHERE SQL_ID = 'gm2npz344xqn8';
CHILD_NUMBER CPU_TIME ELAPSED_TIME BUFFER_GETS
------------ ---------- ------------ -----------
0 92006 131485 1831
1 12000 24156 60
実行された2つ目の文(子番号1)では、統計フィードバックが使用されました。CPU時間、経過時間およびバッファ取得はいずれも、大幅に低下しています。
order_itemsの問合せに対する計画をEXPLAINします。
たとえば、次の文を使用します。
EXPLAIN PLAN FOR SELECT product_name FROM order_items o, product_information p WHERE o.unit_price = 15 AND quantity > 1 AND p.product_id = o.product_id
PLAN TABLE内に計画を表示します。
たとえば、次の文を実行します。
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
出力例は次のように表示されます。
-------------------------------------------------------------------------------
|Id| Operation | Name |Rows|Bytes|Cost (%CPU)|Time|
-------------------------------------------------------------------------------
| 0| SELECT STATEMENT | |4|128|7 (0)|00:00:01|
| 1| NESTED LOOPS | | | | | |
| 2| NESTED LOOPS | |4|128|7 (0)|00:00:01|
|*3| TABLE ACCESS FULL |ORDER_ITEMS |4|48 |3 (0)|00:00:01|
|*4| INDEX UNIQUE SCAN |PRODUCT_INFORMATION_PK|1| |0 (0)|00:00:01|
| 5| TABLE ACCESS BY INDEX ROWID|PRODUCT_INFORMATION |1|20 |1 (0)|00:00:01|
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter("O"."UNIT_PRICE"=15 AND "QUANTITY">1)
4 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID")
この計画では、オプティマイザは、ネステッド・ループ結合を選択します。
以前にEXPLAINした問合せを実行します。
たとえば、次の文を使用します。
SELECT product_name FROM order_items o, product_information p WHERE o.unit_price = 15 AND quantity > 1 AND p.product_id = o.product_id
カーソル内に計画を表示します。
たとえば、次のコマンドを実行します。
SET LINESIZE 165 SET PAGESIZE 0 SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY(FORMAT=>'+ADAPTIVE'));
出力例は次のように表示されます。実行時(手順4)に収集された統計に基づいて、オプティマイザは、ネステッド・ループ結合ではなく、ハッシュ結合を選択します。ダッシュ(-)は、オプティマイザによって考慮されたが最終的に選択されなかった、ネステッド・ループ計画における手順を表します。スイッチは、適応問合せ計画機能を示しています。
------------------------------------------------------------------------------- |Id | Operation | Name |Rows|Bytes|Cost(%CPU)|Time | ------------------------------------------------------------------------------- | 0| SELECT STATEMENT | |4|128|7(0)|00:00:01| | *1| HASH JOIN | |4|128|7(0)|00:00:01| |- 2| NESTED LOOPS | | | | | | |- 3| NESTED LOOPS | | |128|7(0)|00:00:01| |- 4| STATISTICS COLLECTOR | | | | | | | *5| TABLE ACCESS FULL | ORDER_ITEMS |4| 48|3(0)|00:00:01| |-*6| INDEX UNIQUE SCAN | PRODUCT_INFORMATI_PK|1| |0(0)|00:00:01| |- 7| TABLE ACCESS BY INDEX ROWID| PRODUCT_INFORMATION |1| 20|1(0)|00:00:01| | 8| TABLE ACCESS FULL | PRODUCT_INFORMATION |1| 20|1(0)|00:00:01| ------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID") 5 - filter("O"."UNIT_PRICE"=15 AND "QUANTITY">1) 6 - access("P"."PRODUCT_ID"="O"."PRODUCT_ID") Note ----- - this is an adaptive plan (rows marked '-' are inactive)
関連項目:
STATISTICS_LEVEL初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。
DBMS_XPLANの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
パラレル問合せの計画は、シリアル問合せの計画とは重要な点で異なります。
パラレル問合せのチューニングは、パラレルでない問合せのチューニングの場合と同様に駆動表を選択することにより、開始されます。ただし、選択を管理するルールは異なります。
シリアルの場合は、制限条件を適用した後に最も少ない行が生成される駆動表が最適です。データベースは、一意でない索引を使用して少数の行を大きな表に結合します。
たとえば、customer、accountおよびtransactionで構成された表階層の場合について考えます。
この例では、customerが最も小さな表で、transactionが最も大きな表です。通常のOLTP問合せでは、特定の顧客のアカウントに関する取引情報を取得します。問合せはcustomer表から駆動されます。目標は論理I/Oを最少化することで、これにより、通常、物理I/OやCPUタイムを含むその他の重要なリソースも最少化されます。
パラレル問合せの場合は、通常では最も大きな表が駆動表になります。この場合はパラレル問合せを使用するのは効率的ではありません。各表からアクセスされる行がごくわずかであるためです。ここで、前月に特定のタイプの取引を持つすべての顧客を識別する必要が生じた場合を考えてみます。customer表には制限条件がないため、問合せは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の処理が追いつかない場合があります。この状況を改善する方法はほとんどありません。
関連項目:
「PLAN_TABLE列」のOTHER_TAG列
EXPLAIN PLANをパラレル問合せとともに使用すると、データベースは1つのパラレル計画をコンパイルおよび実行します。この計画は、QC計画にパラレル・サポートに固有の行ソースを割り当てることで、シリアル計画から導出されます。
2つのパラレル実行サーバー・セットPQモデルで要求される、表キューの行ソース(PX SendおよびPX Receive)、グラニュル・イテレータおよびバッファ・ソートは、パラレル計画に直接挿入されます。この計画は、パラレルで実行された場合はすべてのパラレル実行サーバーで、またシリアルで実行された場合はすべてのQCで、同じ計画となります。
例7-3 パラレル問合せのEXPLAIN PLAN
次の単純な例は、パラレル問合せの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(問合せコーディネータ)を表します。
ビットマップ索引を使用する索引行ソースは、索引のタイプを示す語BITMAPとともにEXPLAIN PLAN出力に表示されます。
注意:
ビットマップ結合索引を使用した問合せは、ビットマップ結合索引のアクセス・パスを指示します。ビットマップ結合索引の操作は、ビットマップ索引と同じです。
例7-4 ビットマップ検索によるEXPLAIN PLAN
この例では、述語c1=2によってビットマップが生成され、そこから減算が行われます。このビットマップから、c2 = 6に対応するビットマップ内のビットが減算されます。同様に、c2 IS NULLに対応するビットマップ内のビットが減算され、この計画の中に2つのMINUS行ソースがある理由がわかります。NULL減算は、NOT NULL制約が列に設定されていないかぎり、意味上の正確さを保つために必要です。TO ROWIDSオプションは、表アクセスに必要な行IDを生成します。
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
問合せに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ビューに対して問合せを実行できます。
EXPLAIN PLANを使用して、特定の問合せのパーティション化オブジェクトへのOracle Databaseのアクセス方法を表示します。
プルーニング後にアクセスされたパーティションは、PARTITION START列とPARTITION STOP列に表示されます。レンジ・パーティションの行ソース名は、PARTITION RANGEです。ハッシュ・パーティションの場合、行ソース名はPARTITION HASHです。
結合されるいずれかの表のPLAN TABLEのDISTRIBUTION列にPARTITION(KEY)が存在する場合、結合はパーシャル・パーティション・ワイズ結合を使用して実装されます。パーシャル・パーティション・ワイズ結合が可能なのは、結合される表のいずれかが結合列でパーティション化されており、かつ、表がパラレル化されている場合です。
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_TABLEのPARTITION_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のみがアクセスされ、それがコンパイル時に認識されます。したがって、パーティション行ソースは必要ありません。
注意:
ハッシュ・パーティション・オブジェクトでは、パーティション行ソース名がPARTITION RANGEではなくPARTITION HASHであることを除き、同じ情報が表示されます。また、ハッシュ・パーティション化では、プルーニングが可能なのは等価述語かINリスト述語を使用している場合のみです。
Oracle Databaseでコンポジット・パーティション・オブジェクトのプルーニング情報を表示する方法を示すには、表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 Databaseでは単一のサブパーティションのアクセスのみが必要です。このサブパーティションの番号はコンパイル時に認識されるので、ハッシュ・パーティション行ソースは必要ありません。
最後に、次の文を検討します。
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です。手順2では、PARTITION_STARTおよびPARTITION_STOPの両方がKEYに設定されます。この値は、Oracle Databaseでは実行時にサブパーティションの数が決まることを意味します。
例7-5および例7-6では、問合せオプティマイザがこの問合せのコストに基づいて異なる計画を選択する可能性があるため、PQ_DISTRIBUTEヒントにより、パーシャル・パーティション・ワイズ結合が明示的に強制されています。
例7-5 レンジ・パーティション化を使用したパーシャル・パーティション・ワイズ結合
次の例では、emp_range_didがパーティション化列department_idで結合され、パラレル化されます。dept2表がパーティション化されていないことにより、データベースでは、パーシャル・パーティション・ワイズ結合が使用可能になります。Oracle Databaseでは、結合前にdept2表を動的にパーティション化します。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 |Row|Byte|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)、表キューを介して、パーシャル・パーティション・ワイズ結合を実行する同じパラレル実行サーバーに送られることを示します。
例7-6 コンポジット・パーティション化を使用したパーシャル・パーティション・ワイズ結合
次の例では、emp_compがパーティション化列で結合され、パラレル化されます。dept2表がパーティション化されていないことにより、パーシャル・パーティション・ワイズ結合が使用可能になります。データベースでは、結合前にdept2を動的にパーティション化します。
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表が再びパーティション化されることを意味します。
次の例では、emp_compとdept_hashがハッシュ・パーティション化列で結合され、フル・パーティション・ワイズ結合を使用できるようになります。PARTITION HASH行ソースが、PLAN TABLE出力の結合行ソースの上に表示されます。
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 | |
------------------------------------------------------------------------------------------------
PX PARTITION HASH行ソースはPLAN TABLE出力で結合行ソースの上に表示されますが、PX PARTITION RANGE行ソースはemp_compのスキャンにまたがって表示されます。各パラレル実行サーバーは、emp_compのハッシュ・パーティション全体とdept_hashのパーティション全体の結合を実行します。
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リスト列について説明します。
INリスト列empnoが索引列で、パーティション列ではない場合、計画は次のようになります(INリスト演算子は表操作の前に表示されますが、パーティションの操作よりは後に表示されます)。
OPERATION OPTIONS OBJECT_NAME PARTIT_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リスト述語が表示されることを指定します。
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)
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
また、EXPLAIN PLANを使用して、ドメイン索引に対するユーザー定義のCPUおよびI/Oコストを導出できます。EXPLAIN PLANは、これらの統計をPLAN_TABLEのOTHER列に表示します。
たとえば、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
EXPLAIN PLAN文で使用されるPLAN_TABLEには、このトピックで示される列が含まれています。
表7-1 PLAN_TABLE列
| 列 | データ型 | 説明 |
|---|---|---|
|
|
|
|
|
データベース内の計画の一意の識別子です。 |
|
|
|
|
|
実行計画の各ステップに関連付けるコメント(最大80バイト)です。この列は、問合せに使用されたのがアウトラインであるか、SQLプロファイルかを示します。
|
|
|
このステップで実行された内部操作の名前です。文に対して生成された最初の行では、その列に次のいずれかの値が含まれる。
この列の値の詳細は、表7-3を参照してください。 |
|
|
この列の値の詳細は、表7-3を参照してください。 |
|
|
オブジェクト(表名またはビュー名)を参照するために使用されたデータベース・リンクの名前です。パラレル実行を指定したローカル問合せの場合、この列は、処理からの出力をデータベースが使用する順序を説明します。 |
|
|
表または索引を含むスキーマを所有しているユーザーの名前です。 |
|
|
表または索引の名前です。 |
|
|
SQL文に含まれる表またはビューの一意の別名。索引の場合は、基礎となる表のオブジェクトの別名。 |
|
|
元の文に指定されているオブジェクトの位置に対応する順番を示す数値です。番号付けは、元の文テキストの左から右へ、外側から内側へと行われます。ビューを展開した場合、この数値は予測できない。 |
|
|
たとえば、索引に対する |
|
|
オプティマイザの現行モードです。 |
|
|
現在は使用されていません。 |
|
|
実行計画の各ステップに割り当てられた番号です。 |
|
|
|
|
|
計画が示す行ソース・ツリー内の操作の深さ。この値を使用して、PLAN TABLEレポートの行をインデントできます。 |
|
|
最初の出力行の場合、この列はオプティマイザが見積った、文を実行するためのコストを示します。その他の行の場合は、同じ親の他の子に対応する相対位置を示す。 |
|
|
オプティマイザの問合せアプローチによって見積られた操作コストです。表アクセス操作のコストは判断されない。この列の値には、特定の単位はなく、実行計画のコストを比較するために使用される重み値を示します。この列の値は、 |
|
|
この操作がアクセスした行数の問合せ最適化アプローチによる見積りです。 |
|
|
この操作がアクセスしたバイト数の問合せ最適化アプローチによる見積りです。 |
|
|
|
|
|
アクセスしたパーティションの範囲のパーティションを開始します。次のいずれかの値を指定できます。 nは、開始パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。
|
|
|
アクセスされるパーティションの範囲の停止パーティション。次のいずれかの値を指定できます。 nは、終了パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。
|
|
|
|
|
|
ユーザーにとって有効な実行ステップに関するその他の情報です。 |
|
|
プロデューサ問合せサーバーからコンシューマ問合せサーバーへ行を分配する方法です。 この列に使用可能な値の詳細は、表7-2を参照してください。コンシューマ問合せサーバーおよびプロデューサ問合せサーバーの詳細は、Oracle Database VLDBおよびパーティショニング・ガイドを参照してください。 |
|
|
問合せオプティマイザの方法で見積もった操作のCPUコスト。この列の値は、操作に必要なマシン・サイクル数に比例する。ルールベースのアプローチを使用する文の場合、この列はNULLです。 |
|
|
問合せオプティマイザの方法で見積もった操作のI/Oコスト。この列の値は、操作で読み込まれるデータ・ブロック数に比例する。ルールベースのアプローチを使用する文の場合、この列はNULLです。 |
|
|
問合せオプティマイザのアプローチで見積られた、操作で使用される一時領域をバイト単位で表したものです。ルールベース・アプローチを使用する文の場合、または一時領域を使用しない操作の場合、この列はNULLです。 |
|
|
アクセス構造内の行の検索に使用する述語。たとえば、開始述語または停止述語は索引レンジ・スキャンに使用。 |
|
|
フィルタにかけた後で行を生成する場合に使用する述語です。 |
|
|
操作によって生成される式です。 |
|
|
問合せの最適化によって見積られた操作の秒単位の経過時間です。ルールベースのアプローチを使用する文の場合、この列はNULLです。 |
|
|
問合せブロックの名前です。システム生成または |
表7-2では、DISTRIBUTION列に使用される値を説明します。
表7-2 PLAN_TABLEのDISTRIBUTION列の値
| DISTRIBUTIONテキスト | 説明 |
|---|---|
|
|
|
列のセットを使用し、表または索引のパーティション化に基づいて行を問合せサーバーにマップします。パーシャル・パーティション・ワイズ結合、 |
|
結合キーについて、ハッシュ関数を使用して、行を問合せサーバーにマップします。 |
|
ソート・キーの範囲を使用して、行を問合せサーバーにマップします。文に |
|
行を問合せサーバーにランダムにマップします。 |
|
表全体の行を各問合せサーバーにブロードキャストします。ある表がその他の表に比べて非常に小さい場合、パラレル結合に使用します。 |
|
QCは、最初の問合せサーバーから最後の問合せサーバーまで順番に入力データを受け取ります。文に |
|
QCは、入力をランダムに受け取ります。文に |
表7-3に、EXPLAIN PLAN文によって生成されるとOPERATIONOPTIONSの各組合せおよびその実行計画におけるそれぞれの意味を示します。
表7-3 EXPLAIN PLANによって生成されるOPERATION値とOPTIONS値
| 操作 | オプション | 説明 |
|---|---|---|
|
複数のROWIDのセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。この処理は単一列索引のアクセス・パスに対して使用されます。 |
|
|
|
|
|
|
|
|
|
レンジ・スキャンの結果の複数のビットマップを1つのビットマップにマージします。 |
|
|
片方のビットマップのビットを、もう一方のビットマップから減算します。行ソースは否定述語に対して使用されます。このオプションは、減算が発生する可能性があるビットマップを作成する非否定述語がある場合にのみ使用します。「EXPLAIN PLANによるビットマップ索引の表示」で例を示します。 |
|
|
2つのビットマップのビット単位の |
|
|
2つのビットマップのビット単位の |
|
|
表の行ソースから各行を取り出し、ビットマップ索引から対応するビットマップを検索します。その後、このビットマップのセットは、次の |
|
|
|
|
|
複数の行のセットを受け取り、そのセットのUNION-ALLを戻す処理。 |
|
|
表から選択された行の数をカウントする処理。 |
|
|
戻される行数を |
|
|
すべてのキューブ・アクセスで内部結合を使用します。 |
|
|
少なくとも1つのディメンションで外部結合を使用し、その他のディメンションで内部結合を使用します。 |
|
|
すべてのキューブ・アクセスで外部結合を使用します。 |
|
|
ドメイン索引からの1つ以上のROWIDの取出し。オプション列には、ユーザー定義ドメイン・インデックス・コスト関数から与えられた情報が含まれています。 |
|
|
行のセットを受け取り、そのいくつかを取り除き、残りを戻す処理。 |
|
|
問合せで選択される最初の行のみの取出し。 |
|
|
|
|
|
|
|
|
|
(これらは結合操作です。) |
|
2つのセットの行を結合し、結果を戻す操作。この結合方法は、データのラージ・データ・セット(DSSやバッチなど)の結合に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。 問合せオプティマイザは、2つの表またはデータ・ソースの小さいほうを使用して、メモリー内に結合キーについてのハッシュ表を作成します。次に、大きいほうの表をスキャンし、ハッシュ表を調べて結合された行を見つけます。 |
|
|
ハッシュ(左側)アンチ結合。 |
|
|
ハッシュ(左側)セミ結合。 |
|
|
ハッシュ右側アンチ結合。 |
|
|
ハッシュ右側セミ結合。 |
|
|
ハッシュ(左側)外部結合。 |
|
|
ハッシュ(右側)外部結合。 |
(これらはアクセス方法です。) |
|
索引からの単一のROWIDの取出し。 |
|
|
索引からの1つ以上のROWIDの取出し。索引値は昇順でスキャンされます。 |
|
|
索引からの1つ以上のROWIDの取出し。索引値は降順でスキャンされます。 |
|
|
スタート・キーおよびストップ・キーがない場合の、索引からのすべてのROWIDの取得。索引値は昇順でスキャンされます。 |
|
|
スタート・キーおよびストップ・キーがない場合の、索引からのすべてのROWIDの取得。索引値は降順でスキャンされます。 |
|
|
マルチブロックREADを使用した全ROWID(および列の値)の取得。ソート順は定義できません。索引付けされた列に対してのみ、全表スキャンと比較されます。コストベース・オプティマイザでのみ使用可能です。 |
|
|
索引内の先頭列を使用しない、連結索引からのROWIDの取得。コストベース・オプティマイザでのみ使用可能です。 |
|
|
|
|
|
2つの行のセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。 |
(これらは結合操作です。) |
|
2つの行のセットを受け取り、それぞれを特定の値でソートし、一方のセットの各行を他方の行と突き合せて結合し、その結果を戻す処理。 |
|
|
外部結合文を実行するマージ結合処理。 |
|
|
マージ・アンチ結合。 |
|
|
マージ・セミ結合。 |
|
|
文中に他の表への結合条件を持たない1つ以上の表について発生する操作です。結合とともに発生する可能性がありますが、計画内では |
|
|
|
(これらはアクセス方法です。) |
|
マテリアライズド・ビューのすべての行の取出し。 |
|
|
マテリアライズド・ビューのサンプル行の取出し。 |
|
|
索引クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。 |
|
|
ハッシュ・クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。 |
|
|
ROWID範囲に基づいたマテリアライズド・ビューからの行の取出し。 |
|
|
ROWID範囲に基づいたマテリアライズド・ビューからのサンプル行の取出し。 |
|
|
ユーザー指定のROWIDを使用してマテリアライズド・ビューの行が指定される場合。 |
|
|
マテリアライズド・ビューがパーティション化されておらず、索引を使用して行が指定される場合。 |
|
|
マテリアライズド・ビューがパーティション化されており、グローバル索引のみを使用して行が指定される場合。 |
|
|
マテリアライズド・ビューがパーティション化されており、1つ以上のローカル索引と、場合によってはいくつかのグローバル索引を使用して行が指定される場合。 パーティション区間: パーティション区間は次のようにして計算されている可能性があります。 前の
|
|
|
2つの行のセットを受け取り、最初のセットにあって2番目のセットにない行を戻して、重複をなくす処理。 |
(これらは結合操作です。) |
|
外側のセットと内側のセット、2つの行のセットを受け取る処理。Oracle Databaseは、外側のセットの各行を内側のセットの各行と比較し、条件を満たす行を戻します。この結合方法は、小さいサブセットのデータを結合する場合(OLTP)に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。 |
|
|
外部結合文を実行するネステッド・ループ操作。 |
|
|
|
|
|
1つのパーティションへのアクセス。 |
|
|
多数のパーティション(サブセット)へのアクセス。 |
|
|
すべてのパーティションへのアクセス。 |
|
|
|
|
|
アクセスするよう設定されているパーティションが空であることを示します。 |
|
|
パラレル実行サーバー・セット間でのブロックまたはチャンク範囲へのオブジェクトの分割を実装します。 |
|
|
パラレル実行サーバーを使用して下位のパラレル計画を制御、スケジュールおよび実行する問合せコーディネータを実装します。また、パラレルに実行され、常に下位に |
|
|
セマンティクスは通常の |
|
|
|
|
|
スレーブの2つのパラレル実行サーバーの間における配分方法を実装します。2つのセット間の境界と、送信側/プロデューサ側でのデータのパーティション化方法を示します。以前は、この情報は |
|
|
リモート・データベースからのデータの取出し。 |
|
|
順序値のアクセスを伴う処理。 |
|
|
選択した行のグループにグループ関数を適用した結果として取得される単一行の取出し。 |
|
|
行のセットをソートし、重複をなくす処理。 |
|
|
|
|
|
|
|
|
マージ結合の前に、一連の行をソートする操作。 |
|
|
|
(これらはアクセス方法です。) |
|
表のすべての行の取出し。 |
|
|
表のサンプル取得された行の取出し。 |
|
|
索引クラスタのキーの値に基づいた、表からの行の取出し。 |
|
|
ハッシュ・クラスタのキーの値に基づいた、表からの行の取出し。 |
|
|
ROWID範囲に基づいた表からの行の取出し。 |
|
|
ROWID範囲に基づいた表からのサンプル行の取出し。 |
|
|
ユーザー指定のROWIDを使用して表の行が指定される場合。 |
|
|
表がパーティション化されておらず、索引を使用して行が指定される場合。 |
|
|
表がパーティション化されており、グローバル索引のみを使用して行が指定される場合。 |
|
|
表がパーティション化されており、1つ以上のローカル索引と場合によってはいくつかのグローバル索引を使用して、行が指定される場合。 パーティション区間: パーティション区間は次のようにして計算されている可能性があります。 前の
|
|
|
|
|
|
2つの行のセットを受け取り、重複をなくして、そのセットの連結結果を戻す処理。 |
|
|
列から行にデータを回転させる操作。 |
|
|
ビューの問合せを実行し、結果の行を別の処理に戻す処理。 |
関連項目:
PLAN_TABLEの詳細は、Oracle Databaseリファレンスを参照してください。
この項の内容は次のとおりです。
次の動的パフォーマンス・ビューおよびデータ・ディクショナリ・ビューでは、実行計画の情報が提供されます。
表7-4 実行計画のビュー
| ビュー | 説明 |
|---|---|
|
特定の子カーソルが既存の子カーソルと共有されない理由を示します。それぞれの列は、カーソルが共有されない具体的な理由を示します。
|
|
すべての最終計画で使用されているすべての行のスーパーセットが含まれます。 |
|
(ソートまたはハッシュ結合に)SQLメモリーを使用する行ソースのメモリー使用量統計が含まれます。このビューは、 |
PLAN_TABLEはEXPLAIN PLAN文で使用されます。
PLAN_TABLEに含まれる列を表7-5に示します。
表7-5 PLAN_TABLE列
| 列 | データ型 | 説明 |
|---|---|---|
|
|
|
|
|
データベース内の計画の一意の識別子です。 |
|
|
|
|
|
実行計画の各ステップに関連付けるコメント(最大80バイト)です。この列は、問合せに使用されたのがアウトラインであるか、SQLプロファイルかを示します。
|
|
|
このステップで実行された内部操作の名前です。文に対して生成された最初の行では、その列に次のいずれかの値が含まれる。
この列の値の詳細は、表7-6を参照してください。 |
|
|
この列の値の詳細は、表7-6を参照してください。 |
|
|
オブジェクト(表名またはビュー名)を参照するために使用されたデータベース・リンクの名前です。パラレル実行を指定したローカル問合せの場合、この列は、処理からの出力をデータベースが使用する順序を説明します。 |
|
|
表または索引を含むスキーマを所有しているユーザーの名前です。 |
|
|
表または索引の名前です。 |
|
|
SQL文に含まれる表またはビューの一意の別名。索引の場合は、基礎となる表のオブジェクトの別名。 |
|
|
元の文に指定されているオブジェクトの位置に対応する順番を示す数値です。番号付けは、元の文テキストの左から右へ、外側から内側へと行われます。ビューを展開した場合、この数値は予測できない。 |
|
|
オブジェクトに関する情報を示す修飾子(索引に対する |
|
|
オプティマイザの現行モードです。 |
|
|
現在は使用されていません。 |
|
|
実行計画の各ステップに割り当てられた番号です。 |
|
|
|
|
|
計画が示す行ソース・ツリー内の操作の深さ。この値を使用して、PLAN TABLEレポートの行をインデントできます。 |
|
|
最初の出力行の場合、この列はオプティマイザが見積った、文を実行するためのコストを示します。その他の行の場合は、同じ親の他の子に対応する相対位置を示す。 |
|
|
オプティマイザの問合せアプローチによって見積られた操作コストです。表アクセス操作のコストは判断されない。この列の値には、特定の単位はなく、実行計画のコストを比較するために使用される重み値を示します。この列の値は、 |
|
|
この操作がアクセスした行数の問合せ最適化アプローチによる見積りです。 |
|
|
この操作がアクセスしたバイト数の問合せ最適化アプローチによる見積りです。 |
|
|
|
|
|
アクセスしたパーティションの範囲のパーティションを開始します。次のいずれかの値を指定できます。 nは、開始パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。
|
|
|
アクセスされるパーティションの範囲の停止パーティション。次のいずれかの値を指定できます。 nは、終了パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。
|
|
|
|
|
|
ユーザーにとって有効な実行ステップに関するその他の情報です。 |
|
|
プロデューサ問合せサーバーからコンシューマ問合せサーバーへ行を分配する方法です。 この列に使用可能な値の詳細は、表7-6を参照してください。コンシューマ問合せサーバーおよびプロデューサ問合せサーバーの詳細は、Oracle Database VLDBおよびパーティショニング・ガイドを参照してください。 |
|
|
問合せオプティマイザの方法で見積もった操作のCPUコスト。この列の値は、操作に必要なマシン・サイクル数に比例する。ルールベースのアプローチを使用する文の場合、この列はNULLです。 |
|
|
問合せオプティマイザの方法で見積もった操作のI/Oコスト。この列の値は、操作で読み込まれるデータ・ブロック数に比例する。ルールベースのアプローチを使用する文の場合、この列はNULLです。 |
|
|
問合せオプティマイザのアプローチで見積られた、操作で使用される一時領域をバイト単位で表したものです。ルールベース・アプローチを使用する文の場合、または一時領域を使用しない操作の場合、この列はNULLです。 |
|
|
アクセス構造内の行の検索に使用する述語。たとえば、開始述語または停止述語は索引レンジ・スキャンに使用。 |
|
|
フィルタにかけた後で行を生成する場合に使用する述語です。 |
|
|
操作によって生成される式です。 |
|
|
問合せの最適化によって見積られた操作の秒単位の経過時間です。ルールベースのアプローチを使用する文の場合、この列はNULLです。 |
|
|
問合せブロックの名前です。システム生成または |
表7-6 PLAN_TABLEのDISTRIBUTION列の値
| DISTRIBUTIONテキスト | 説明 |
|---|---|
|
|
|
列のセットを使用し、表または索引のパーティション化に基づいて行を問合せサーバーにマップします。パーシャル・パーティション・ワイズ結合、 |
|
結合キーについて、ハッシュ関数を使用して、行を問合せサーバーにマップします。 |
|
ソート・キーの範囲を使用して、行を問合せサーバーにマップします。文に |
|
行を問合せサーバーにランダムにマップします。 |
|
表全体の行を各問合せサーバーにブロードキャストします。ある表がその他の表に比べて非常に小さい場合、パラレル結合に使用します。 |
|
QCは、最初の問合せサーバーから最後の問合せサーバーまで順番に入力データを受け取ります。文に |
|
QCは、入力をランダムに受け取ります。文に |
表7-7に、EXPLAIN PLAN文によって生成されるOPERATIONとOPTIONSの各組合せおよびその実行計画におけるそれぞれの意味を示します。
表7-7 EXPLAIN PLANによって生成されるOPERATION値とOPTIONS値
| 操作 | オプション | 説明 |
|---|---|---|
|
複数のROWIDのセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。この処理は単一列索引のアクセス・パスに対して使用されます。 |
|
|
|
|
|
|
|
|
|
レンジ・スキャンの結果の複数のビットマップを1つのビットマップにマージします。 |
|
|
片方のビットマップのビットを、もう一方のビットマップから減算します。行ソースは否定述語に対して使用されます。このオプションは、減算が発生する可能性があるビットマップを作成する非否定述語がある場合にのみ使用できます。 |
|
|
2つのビットマップのビット単位の |
|
|
2つのビットマップのビット単位の |
|
|
表の行ソースから各行を取り出し、ビットマップ索引から対応するビットマップを検索します。その後、このビットマップのセットは、次の |
|
|
|
|
|
複数の行のセットを受け取り、そのセットのUNION-ALLを戻す処理。 |
|
|
表から選択された行の数をカウントする処理。 |
|
|
戻される行数を |
|
|
左側の表またはビューおよび右側のキューブを結合します。
|
|
|
左側の表またはビューおよび右側のキューブに対してアンチ結合を使用します。 |
|
|
左側の表またはビューおよび右側のキューブに対してアンチ結合(片面NULL対応)を使用します。右側の結合列(キューブ側)は |
|
|
左側の表またはビューおよび右側のキューブに対して外部結合を使用します。 |
|
|
左側の表またはビューおよび右側のキューブに対して右側セミ結合を使用します。 |
|
|
すべてのキューブ・アクセスで内部結合を使用します。 |
|
|
少なくとも1つのディメンションで外部結合を使用し、その他のディメンションで内部結合を使用します。 |
|
|
すべてのキューブ・アクセスで外部結合を使用します。 |
|
|
ドメイン索引からの1つ以上のROWIDの取出し。オプション列には、ユーザー定義ドメイン・インデックス・コスト関数から与えられた情報が含まれています。 |
|
|
行のセットを受け取り、そのいくつかを取り除き、残りを戻す処理。 |
|
|
問合せで選択される最初の行のみの取出し。 |
|
|
|
|
|
|
|
|
|
(これらは結合操作です。) |
|
2つのセットの行を結合し、結果を戻す操作。この結合方法は、データのラージ・データ・セット(DSSやバッチなど)の結合に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。 問合せオプティマイザは、2つの表またはデータ・ソースの小さいほうを使用して、メモリー内に結合キーについてのハッシュ表を作成します。次に、大きいほうの表をスキャンし、ハッシュ表を調べて結合された行を見つけます。 |
|
|
ハッシュ(左側)アンチ結合。 |
|
|
ハッシュ(左側)セミ結合。 |
|
|
ハッシュ右側アンチ結合。 |
|
|
ハッシュ右側セミ結合。 |
|
|
ハッシュ(左側)外部結合。 |
|
|
ハッシュ(右側)外部結合。 |
(これらはアクセス方法です。) |
|
索引からの単一のROWIDの取出し。 |
|
|
索引からの1つ以上のROWIDの取出し。索引値は昇順でスキャンされます。 |
|
|
索引からの1つ以上のROWIDの取出し。索引値は降順でスキャンされます。 |
|
|
スタート・キーおよびストップ・キーがない場合の、索引からのすべてのROWIDの取得。索引値は昇順でスキャンされます。 |
|
|
スタート・キーおよびストップ・キーがない場合の、索引からのすべてのROWIDの取得。索引値は降順でスキャンされます。 |
|
|
マルチブロックREADを使用した全ROWID(および列の値)の取得。ソート順は定義できません。索引付けされた列に対してのみ、全表スキャンと比較されます。コストベース・オプティマイザでのみ使用可能です。 |
|
|
索引内の先頭列を使用しない、連結索引からのROWIDの取得。コストベース・オプティマイザでのみ使用可能です。 |
|
|
|
|
|
2つの行のセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。 |
(これらは結合操作です。) |
|
2つの行のセットを受け取り、それぞれを特定の値でソートし、一方のセットの各行を他方の行と突き合せて結合し、その結果を戻す処理。 |
|
|
外部結合文を実行するマージ結合処理。 |
|
|
マージ・アンチ結合。 |
|
|
マージ・セミ結合。 |
|
|
文中に他の表への結合条件を持たない1つ以上の表について発生する操作です。結合とともに発生する可能性がありますが、計画内では |
|
|
|
(これらはアクセス方法です。) |
|
マテリアライズド・ビューのすべての行の取出し。 |
|
|
マテリアライズド・ビューのサンプル行の取出し。 |
|
|
索引クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。 |
|
|
ハッシュ・クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。 |
|
|
ROWID範囲に基づいたマテリアライズド・ビューからの行の取出し。 |
|
|
ROWID範囲に基づいたマテリアライズド・ビューからのサンプル行の取出し。 |
|
|
ユーザー指定のROWIDを使用してマテリアライズド・ビューの行が指定される場合。 |
|
|
マテリアライズド・ビューがパーティション化されておらず、索引を使用して行が指定される場合。 |
|
|
マテリアライズド・ビューがパーティション化されており、グローバル索引のみを使用して行が指定される場合。 |
|
|
マテリアライズド・ビューがパーティション化されており、1つ以上のローカル索引と、場合によってはいくつかのグローバル索引を使用して行が指定される場合。 パーティション区間: パーティション区間は次のようにして計算されている可能性があります。 前の
|
|
|
2つの行のセットを受け取り、最初のセットにあって2番目のセットにない行を戻して、重複をなくす処理。 |
(これらは結合操作です。) |
|
外側のセットと内側のセット、2つの行のセットを受け取る処理。Oracle Databaseは、外側のセットの各行を内側のセットの各行と比較し、条件を満たす行を戻します。この結合方法は、小さいサブセットのデータを結合する場合(OLTP)に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。 |
|
|
外部結合文を実行するネステッド・ループ操作。 |
|
|
|
|
|
1つのパーティションへのアクセス。 |
|
|
多数のパーティション(サブセット)へのアクセス。 |
|
|
すべてのパーティションへのアクセス。 |
|
|
|
|
|
アクセスするよう設定されているパーティションが空であることを示します。 |
|
|
パラレル実行サーバー・セット間でのブロックまたはチャンク範囲へのオブジェクトの分割を実装します。 |
|
|
パラレル実行サーバーを使用して下位のパラレル計画を制御、スケジュールおよび実行する問合せコーディネータを実装します。また、パラレルに実行され、常に下位に |
|
|
セマンティクスは通常の |
|
|
PX SENDノード上で実行される送信側/プロデューサ(QCまたはパラレル実行サーバー)から再パーティション化されたデータを読み取る、コンシューマ/受信側パラレル実行ノードを示します。以前は、この情報は |
|
|
スレーブの2つのパラレル実行サーバー・セットの間における配分方法を実装します。2つのセット間の境界と、送信側/プロデューサ側(QCまたはスレーブ)でのデータのパーティション化方法を示します。以前は、この情報は |
|
|
リモート・データベースからのデータの取出し。 |
|
|
順序値のアクセスを伴う処理。 |
|
|
選択した行のグループにグループ関数を適用した結果として取得される単一行の取出し。 |
|
|
行のセットをソートし、重複をなくす処理。 |
|
|
|
|
|
|
|
|
マージ結合の前に、一連の行をソートする操作。 |
|
|
|
(これらはアクセス方法です。) |
|
表のすべての行の取出し。 |
|
|
表のサンプル取得された行の取出し。 |
|
|
索引クラスタのキーの値に基づいた、表からの行の取出し。 |
|
|
ハッシュ・クラスタのキーの値に基づいた、表からの行の取出し。 |
|
|
ROWID範囲に基づいた表からの行の取出し。 |
|
|
ROWID範囲に基づいた表からのサンプル行の取出し。 |
|
|
ユーザー指定のROWIDを使用して表の行が指定される場合。 |
|
|
表がパーティション化されておらず、索引を使用して行が指定される場合。 |
|
|
表がパーティション化されており、グローバル索引のみを使用して行が指定される場合。 |
|
|
表がパーティション化されており、1つ以上のローカル索引と場合によってはいくつかのグローバル索引を使用して、行が指定される場合。 パーティション区間: パーティション区間は次のようにして計算されている可能性があります。 前の
|
|
|
|
|
|
2つの行のセットを受け取り、重複をなくして、そのセットの連結結果を戻す処理。 |
|
|
列から行にデータを回転させる操作。 |
|
|
ビューの問合せを実行し、結果の行を別の処理に戻す処理。 |
関連項目:
PLAN_TABLEの詳細は、Oracle Databaseリファレンスを参照してください。
DBMS_XPLANのファンクションDISPLAY_PLANおよびDISPLAY_CURSORは、適応計画のアクセスに関連します。
表7-8 適応問合せに関連するDBMS_XPLAN関数およびパラメータ
| 関数 | 注意 |
|---|---|
|
フォーマット引数にアウトライン表示が指定されると、関数では、動的サブプラン内の各オプションに対するヒントが表示されます。計画が適応問合せ計画でない場合、関数ではデフォルトの計画が表示されます。 |
|
|
関連項目:
DBMS_XPLANの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください