この章では、実行計画について紹介し、SQL文EXPLAIN PLANを解説し、その出力の解釈方法を説明します。さらに、アプリケーションのパフォーマンス特性を制御するアウトラインを管理するプロシージャを示します。
この章には次の項があります。
EXPLAIN PLAN文は、SELECT、UPDATE、INSERTおよびDELETE文についてOracleオプティマイザが選択した実行計画を表示します。文の実行計画とは、Oracleがその文を実行するために行う一連の処理です。
行ソース・ツリーは、実行計画の中核です。行ソース・ツリーは次の情報を示します。
文によって参照される表の順序
文で言及される各表へのアクセス方法
文の結合操作の影響を受ける表の結合方法
フィルタ、ソート、集計などのデータ操作
PLAN TABLEには、行ソース・ツリーの他、次の情報が含まれています。
最適化。各操作のコストとカーディナリティについて。
パーティション化。アクセスされたパーティションのセットなど。
パラレル実行。結合入力の配分方法など。
EXPLAIN PLANの結果により、オプティマイザが特定の実行計画(たとえば、ネステッド・ループ結合)を選択するかどうかを判断できます。また、オプティマイザの決定(たとえば、オプティマイザがハッシュ結合でなくネステッド・ループ結合を選択した理由)について理解し、問合せのパフォーマンスを知るために役立ちます。
|
注意: Oracle Performance ManagerチャートとOracle SQL Analyzeは、EXPLAIN PLANを自動的に作成して表示できます。EXPLAIN PLANの使用方法の詳細は、『Oracle Enterprise Manager概要』を参照してください。 |
問合せオプティマイザを使用すると、実行計画は基礎となるオプティマイザ入力が変化するたびに変化します。EXPLAIN PLANの出力は、SQL文の説明段階での実行方法を示します。この方法は、実行環境とEXPLAIN PLAN環境との違いにより、SQL文の実際の実行計画とは異なる場合があります。
|
注意: 実行計画の変更から生じる可能性があるSQLパフォーマンスの低下を回避するには、SQL計画の管理を使用することを検討してください。詳細は、第15章「SQL計画の管理の使用方法」を参照してください。 |
実行計画は、次の理由により異なります。
実行とEXPLAIN PLANが、異なるデータベース上で起こる場合。
文をEXPLAINするユーザーが、文を実行するユーザーとは異なる場合。2人のユーザーが同じデータベース内の異なるオブジェクトを指していれば、異なる実行計画が発生します。
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)
実行計画の操作のみでは、よく調整された文とうまく機能しない文を区別できません。たとえば、文による索引の使用がEXPLAIN PLAN出力で示されたとしても、その文が効率的に機能するとはかぎりません。索引は、非常に非効率的である場合もあります。この場合、次のことを調べる必要があります。
使用される索引の列
その索引の選択性(アクセスされる表の一部)
したがって、EXPLAIN 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情報が結合されます。
|
関連項目:
|
すべてのユーザーの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;
SQL文をEXPLAINする場合は、文の直前にEXPLAIN PLAN FOR句を使用します。たとえば、次のようにします。
EXPLAIN PLAN FOR SELECT last_name FROM employees;
計画をEXPLAINしたものがPLAN_TABLE表に挿入されます。PLAN_TABLEから実行計画を選択できるようになります。「PLAN_TABLE出力の表示」を参照してください。
複数の文があるときは、文の識別子を指定し、その識別子で特定の実行計画を識別できます。SET STATEMENT IDを使用する前に、その文と同じ識別子を持つ既存の行を削除してください。
例12-3の場合は、st1が文の識別子として指定されています。
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言語リファレンス』を参照してください。 |
計画をEXPLAINした後、Oracle Databaseから提供される次のSQLスクリプトまたはPL/SQLパッケージを使用して最新のPLAN TABLE出力を表示します。
このスクリプトは、シリアル処理のためのPLAN TABLE出力を表示します。例11-2「EXPLAIN PLAN出力」は、UTLXPLS.SQLスクリプトを使用した場合のPLAN TABLE出力の例です。
このスクリプトは、パラレル実行列を含むPLAN TABLE出力を表示します。
DBMS_XPLAN.DISPLAYテーブル・ファンクション
このファンクションは、PLAN TABLE出力を表示するオプションを受け入れます。指定できるのは次のとおりです。
PLAN_TABLEとは別の表を使用している場合のPLAN TABLE名
EXPLAIN PLANに文の識別子を設定した場合の文の識別子
詳細レベルを決定するフォーマット・オプション: BASIC、SERIALおよびTYPICAL、ALL
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パッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
文の識別子を指定した場合は、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の場合には有効ではありません。 |
この項では、EXPLAIN PLANの例を使用して実行計画を説明します。例12-5の文は、実行計画の表示に使用されます。
例12-5 EXPLAIN PLANを表示する文
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'statement_id','BASIC'));
例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は、全表スキャンでアクセスされます。
表employeesのすべての行がアクセスされ、各行がWHERE句の条件に基づいて評価されます。
SELECT文により、WHERE句の条件に一致する行が戻されます。
例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文の実行を示します。
索引EMP_NAME_IXは、レンジ・スキャン操作でWHERE句の条件を評価するために使用されます。
SELECT文により、WHERE句の条件を満たす行が戻されます。
パラレル問合せのチューニングは、パラレルでない問合せのチューニングの場合と同様に駆動表を選択することにより、開始されます。ただし、選択を管理するルールは異なります。パラレルでない問合せの場合は、通常、制限条件が適用された後に最も少ない行が生成される駆動表が最適です。少数の行は、一意でない索引を使用して大きな表に結合されます。たとえば、CUSTOMER、ACCOUNTおよび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)がそれらの行を生成後すぐに処理できない場合があります。このような状況を改善する方法はありません。
パラレル問合せに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(問合せコーディネータ)を表します。
ビットマップ索引を使用する索引行ソースは、索引のタイプを示すワード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を生成するのに使用されます。
|
注意: ビットマップ結合索引を使用した問合せは、ビットマップ結合索引のアクセス・パスを指示します。ビットマップ結合索引の操作は、ビットマップ索引と同じです。 |
問合せに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がアクセスする方法を参照できます。
プルーニング後にアクセスされたパーティションは、PARTITION START列とPARTITION STOP列に表示されます。レンジ・パーティションの行ソース名は、PARTITION RANGEです。ハッシュ・パーティションの場合、行ソース名はPARTITION HASHです。
結合されるいずれかの表のPLAN TABLEのDISTRIBUTION列にPARTITION(KEY)が存在する場合、結合はパーシャル・パーティション・ワイズ結合を使用して実装されます。パーシャル・パーティション・ワイズ結合が可能なのは、結合される表のいずれかが結合列でパーティション化されており、かつ、表がパラレル化されている場合です。
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_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 |
--------------------------------------------------------------------------------------
前の例では、パーティション行ソースがパーティション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のみがアクセスされ、それがコンパイル時に認識されます。したがって、パーティション行ソースは必要ありません。
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_STOPはKEYに設定されます。これは、Oracleがサブパーティションの番号を実行時に判別することを意味します。
次の例では、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ヒントが使用されていることに注意してください。
次の例では、emp_compとdept_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 | | -------------------------------------------------------------------------------------------------------------
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 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リスト述語が表示されます。
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をサポートしている場合に、次の問合せをします。
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には、表12-1に示す列があります。
表12-1 PLAN_TABLE列
| 列 | 型 | 説明 |
|---|---|---|
|
|
|
|
|
|
|
データベース内の計画の一意の識別子です。 |
|
|
|
|
|
|
|
実行計画の各ステップに関連付けるコメント(最大80バイト)です。この列は、問合せにアウトラインが使用されたかSQLプロファイルが使用されたかを示すために使用されます。
|
|
|
|
このステップで実行された内部操作の名前です。文に対して生成された最初の行の列には、次の値の1つが含まれます。
この列の値の詳細は、表12-3を参照してください。 |
|
|
|
この列の値の詳細は、表12-3を参照してください。 |
|
|
|
オブジェクト(表名またはビュー名)を参照するために使用されたデータベース・リンクの名前です。パラレル実行を指定したローカル問合せの場合は、各処理による出力の使用順序がこの列に記述されます。 |
|
|
|
|
|
|
|
|
|
|
|
SQL文に含まれる表またはビューの一意の別名です。索引の場合は、基礎となる表のオブジェクトの別名です。 |
|
|
|
元の文に指定されているオブジェクトの位置に対応する順番を示す数値です。この数値は元の文テキストに関して、左から右へ、外側から内側へ付番されています。ビューを展開した場合、この数値は予測できません。 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
計画により表される行ソース・ツリー内の操作の深さです。この値を使用して、PLAN TABLEレポートの行をインデントできます。 |
|
|
|
最初の出力行の場合、この列はオプティマイザが見積った、文を実行するためのコストを示します。その他の行の場合は、同じ親の他の子に対応する相対位置を示します。 |
|
|
|
オプティマイザの問合せアプローチによって見積られた操作コストです。表アクセス操作のためのコストは判断されません。この列の値には、特定の単位はなく、単に実行計画のコストを比較するために使用される重み値を示します。この列の値は、 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
アクセスされるパーティション範囲の開始パーティションです。これは、次のいずれかの値をとります。 nは、開始パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。
|
|
|
|
アクセスされるパーティション範囲の終了パーティションです。これは、次のいずれかの値をとります。 nは、終了パーティションがSQLコンパイラで識別され、そのパーティション番号がnで示されることを意味します。
|
|
|
|
|
|
|
|
|
|
|
|
プロデューサ問合せサーバーからコンシューマ問合せサーバーへ行を分配する方法です。 この列に使用可能な値の詳細は、表12-2を参照してください。コンシューマ問合せサーバーおよびプロデューサ問合せサーバーの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください。 |
|
|
|
問合せオプティマイザのアプローチによって見積られた操作のCPUコストです。この列の値は、操作に必要なマシン・サイクル数に比例します。ルールベース・アプローチを使用する文では、この列はNULLになります。 |
|
|
|
問合せオプティマイザのアプローチによって見積られた操作のI/Oコストです。この列の値は、操作で読み取られるデータ・ブロックの数に比例します。ルールベース・アプローチを使用する文では、この列はNULLになります。 |
|
|
|
問合せオプティマイザのアプローチで見積られた、操作で使用される一時領域をバイト単位で表したものです。ルールベース・アプローチを使用する文の場合、または一時領域を使用しない操作の場合、この列はNULLです。 |
|
|
|
アクセス構造の行を特定する場合に使用する述語です。たとえば、索引レンジ・スキャンの開始や停止の述語などがあります。 |
|
|
|
フィルタにかけた後で行を生成する場合に使用する述語です。 |
|
|
|
操作によって生成される式です。 |
|
|
|
問合せの最適化によって見積られた操作の秒単位の経過時間です。ルールベース・アプローチを使用する文では、この列はNULLになります。 |
|
|
|
問合せブロックの名前です。システム生成または |
表12-2で、DISTRIBUTION列に使用される値を説明します。
表12-2 PLAN_TABLEのDISTRIBUTION列の値
| DISTRIBUTIONテキスト | 説明 |
|---|---|
|
|
|
|
|
列のセットを使用し、表または索引のパーティション化に基づいて行を問合せサーバーにマップします。パーシャル・パーティション・ワイズ結合、 |
|
|
結合キーについて、ハッシュ関数を使用して、行を問合せサーバーにマップします。 |
|
|
ソート・キーの範囲を使用して、行を問合せサーバーにマップします。文に |
|
|
行を問合せサーバーにランダムにマップします。 |
|
|
表全体の行を各問合せサーバーにブロードキャストします。ある表がその他の表に比べて非常に小さい場合、パラレル結合に使用します。 |
|
|
問合せコーディネータ(QC)が、最初の問合せサーバーから最後の問合せサーバーまで順番に入力データを受け取ります。文に |
|
|
問合せコーディネータ(QC)が、入力データをランダムに受け取ります。文に |
表12-3に、EXPLAIN PLAN文によって生成されるOPERATIONとOPTIONSの各組合せおよびその実行計画におけるそれぞれの意味を示します。
表12-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の取得。Oracle9iで導入されています。コストベース・オプティマイザでのみ使用可能です。 |
|
|
|
|
|
|
|
2つの行のセットを受け取り、重複をなくして、そのセットの共通部分を戻す処理。 |
|
(これらは結合操作です。) |
|
2つの行のセットを受け取り、それぞれを特定の値でソートし、一方のセットの各行を他方の行と突き合せて結合し、その結果を戻す処理。 |
|
|
|
外部結合文を実行するマージ結合処理。 |
|
|
|
マージ・アンチ結合。 |
|
|
|
マージ・セミ結合。 |
|
|
|
文中に他の表への結合条件を持たない1つ以上の表について発生する操作です。結合とともに発生する可能性がありますが、計画内では |
|
|
|
|
|
(これらはアクセス方法です。) |
|
マテリアライズド・ビューのすべての行の取出し。 |
|
|
|
マテリアライズド・ビューのサンプル行の取出し。 |
|
|
|
索引クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。 |
|
|
|
ハッシュ・クラスタのキーの値に基づいた、マテリアライズド・ビューからの行の取出し。 |
|
|
|
ROWID範囲に基づいたマテリアライズド・ビューからの行の取出し。 |
|
|
|
ROWID範囲に基づいたマテリアライズド・ビューからのサンプル行の取出し。 |
|
MAT_VIEW REWITE ACCESS |
|
ユーザー指定のROWIDを使用してマテリアライズド・ビューの行が指定される場合。 |
|
|
|
マテリアライズド・ビューがパーティション化されておらず、索引を使用して行が指定される場合。 |
|
|
|
マテリアライズド・ビューがパーティション化されており、グローバル索引のみを使用して行が指定される場合。 |
|
|
|
マテリアライズド・ビューがパーティション化されており、1つ以上のローカル索引と、場合によってはいくつかのグローバル索引を使用して行が指定される場合。 パーティション区間: パーティション区間は次のようにして計算されている可能性があります。 前の
|
|
|
|
2つの行のセットを受け取り、最初のセットにあって2番目のセットにない行を戻して、重複をなくす処理。 |
|
(これらは結合操作です。) |
|
外側のセットと内側のセット、2つの行のセットを受け取る処理。Oracleは、外側のセットの各行を内側のセットの各行と比較し、条件を満たす行を戻します。この結合方法は、小さいサブセットのデータを結合する場合(OLTP)に役立ちます。この結合条件は、第2の表にアクセスする場合に有効です。 |
|
|
|
外部結合文を実行するネステッド・ループ操作。 |
|
|
. |
|
|
|
|
1つのパーティションへのアクセス。 |
|
|
|
多数のパーティション(サブセット)へのアクセス。 |
|
|
|
すべてのパーティションへのアクセス。 |
|
|
|
|
|
|
|
アクセスするよう設定されているパーティションが空であることを示します。 |
|
|
|
パラレル・スレーブ・セット間でのブロックまたはチャンク範囲へのオブジェクトの分割を実装します。 |
|
|
. |
パラレル問合せスレーブを使用して下位のパラレル計画を制御、スケジュールおよび実行する問合せコーディネータを実装します。また、パラレルに実行され、常に下位に |
|
|
. |
セマンティクスは通常の |
|
|
. |
PX SENDノード上で実行される送信側/プロデューサ(QCまたはスレーブ)からパーティション化されたデータを読み取る、コンシューマ/受信側スレーブ・ノードを示します。以前は、この情報は |
|
|
|
スレーブの2つのパラレル・セットの間における配分方法を実装します。2つのスレーブ・セット間の境界と、送信側/プロデューサ側(QCまたはスレーブ)でのデータのパーティション化方法を示します。以前は、この情報は |
|
|
|
リモート・データベースからのデータの取出し。 |
|
|
|
順序値のアクセスを伴う処理。 |
|
|
|
選択した行のグループにグループ関数を適用した結果として取得される単一行の取出し。 |
|
|
|
行のセットをソートし、重複をなくす処理。 |
|
|
|
|
|
|
|
|
|
|
|
マージ結合の前に、一連の行をソートする操作。 |
|
|
|
|
|
(これらはアクセス方法です。) |
|
表のすべての行の取出し。 |
|
|
|
表のサンプル取得された行の取出し。 |
|
|
|
索引クラスタのキーの値に基づいた、表からの行の取出し。 |
|
|
|
ハッシュ・クラスタのキーの値に基づいた、表からの行の取出し。 |
|
|
|
ROWID範囲に基づいた表からの行の取出し。 |
|
|
|
ROWID範囲に基づいた表からのサンプル行の取出し。 |
|
|
|
ユーザー指定のROWIDを使用して表の行が指定される場合。 |
|
|
|
表がパーティション化されておらず、索引を使用して行が指定される場合。 |
|
|
|
表がパーティション化されており、グローバル索引のみを使用して行が指定される場合。 |
|
|
|
表がパーティション化されており、1つ以上のローカル索引と場合によってはいくつかのグローバル索引を使用して、行が指定される場合。 パーティション区間: パーティション区間は次のようにして計算されている可能性があります。 前の
|
|
|
|
|
|
|
|
2つの行のセットを受け取り、重複をなくして、そのセットの連結結果を戻す処理。 |
|
|
|
列から行にデータを回転させる操作。 |
|
|
|
ビューの問合せを実行し、結果の行を別の処理に戻す処理。 |
|
関連項目: PLAN_TABLEの詳細は、『Oracle Databaseリファレンス』を参照してください。 |