本文書に関する指摘については、原文著者のTanel Poderさんではなく、渡部まで御連絡お願いいたします。
注意事項
- 自動翻訳に手を加えたレベルの翻訳と理解してください
- 意味をとりやすくするために追加した箇所については、《…》で囲っています。
- 訳がわからない、または、自信がない箇所は★をつけています。
日本語訳:渡部 亮太 (WR at Csus4 dot net)
履歴
- 2013-04-09: 初稿up
ALTER SESSION FORCE PARALLEL QUERYは、実際に何かを強制するものではありません
PARALLELヒントの観点から、ジョナサン?ルイスがこの動作について、既に書いています。
私はただのALTER SESSION FORCE PARALLEL QUERY構文におけるFORCEというワードについて、同様の記事を書きます。FORCEとは、(可能な場合は)なにかしらの動作が常に起こることを意味するべきでしょうか?テストしてみましょう:
SQL> CREATE TABLE t AS SELECT * FROM dba_objects;
Table created.
SQL> CREATE INDEX i ON t(owner);
Index created.
SQL> @gts t
Gather Table Statistics for table t...
PL/SQL procedure successfully completed.
では、私のセッションで、並列クエリを"強制(force)"してみましょう。クエリを実行し、実行計画を確認してください。
SQL> ALTER SESSION FORCE PARALLEL QUERY PARALLEL 2;
Session altered.
SQL> SELECT SUM(object_id) FROM t WHERE owner LIKE 'S%';
SUM(OBJECT_ID)
\--------------
979900956
SQL> @x
\---------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)|
\---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 186 (100)|
| 1 | SORT AGGREGATE | | 1 | 12 | |
| 2 | TABLE ACCESS BY INDEX ROWID| T | 6741 | 80892 | 186 (0)|
|* 3 | INDEX RANGE SCAN | I | 6741 | | 18 (0)|
\---------------------------------------------------------------------------
Predicate Information (identified by operation id):
\---------------------------------------------------
3 - access("OWNER" LIKE 'S%')
filter("OWNER" LIKE 'S%')
出力は、通常のシリアル実行計画を示しています!
うーん、2から3に"強制された"並列度を増やし、再度まったく同じクエリを実行してみましょう:
SQL> ALTER SESSION FORCE PARALLEL QUERY PARALLEL 3;
Session altered.
SQL> SELECT SUM(object_id) FROM t WHERE owner LIKE 'S%';
SUM(OBJECT_ID)
\--------------
979900956
SQL> @x
\------------------------------------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| TQ |IN-OUT| PQ Distrib |
\------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 128 (100)| | | |
| 1 | SORT AGGREGATE | | 1 | 12 | | | | |
| 2 | PX COORDINATOR | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 12 | | Q1,00 | P->S | QC (RAND) |
| 4 | SORT AGGREGATE | | 1 | 12 | | Q1,00 | PCWP | |
| 5 | PX BLOCK ITERATOR | | 6741 | 80892 | 128 (0)| Q1,00 | PCWC | |
|* 6 | TABLE ACCESS FULL| T | 6741 | 80892 | 128 (0)| Q1,00 | PCWP | |
\------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
\---------------------------------------------------
6 - access(:Z>=:Z AND :Z<=:Z)
filter("OWNER" LIKE 'S%')
ほら、クエリがパラレルの実行計画になりました!
この現象の理由は、FORCE並列クエリの構文は、Oracleにパラレルの実行計画を使用するように強制するのではなくて、単にフル?テーブル?スキャン のコストを小さくすることにあります。(より高い並列性《を指定すれば》、フル・テーブルスキャンのコストがより小さくなる — 詳細については、ジョナサンが既に彼のブログエントリで書いているため、私はこれを複製しません。)しかし、それが最もよいパラレル実行計画よりも低いコストを持っているならば、オプティマイザは、まだいくつかの他の非パラレルの実行計画を自由に選択できます!
したがって、上で起こったことは、 "強制"並列度2が指定された、パラレル全表スキャンの実行計画は、シリアル索引レンジ?スキャン(186)よりも、高いコストを持っていたに違いないということと、parallelism "因子(factor)"を3に増加させると、パラレルのフル?テーブル?スキャン実行計画の最終的なコスト(128)が、これまでに見つかったもっとも優れたシリアルの実行計画より小さくなったことである。
これは、PARALLELヒントおよびFORCE PARALLELセッションの設定が、オプティマイザのコスト計算への入力の限定されたセットを調整するだけであり、結果となる実行計画を修正するわけでないないことを示す良い例です。あなたが本当に実行計画を固定したい場合は、ストアドプロファイルが行うように、あらゆる面で、オプティマイザとヒントの完全なセットを "結びつける"必要があります。ヒントが指示する以外の《実行計画のコスト》計算は禁止されているため、使用可能な低いコストの実行計画があっても、オプティマイザーはそれを知ることはありません。
これをテストするとき、有用性は、テストテーブルにどのくらいのデータがあるか(またはむしろ、そのテーブルのオプティマイザ統計)と、システム統計情報によって異なる場合がありますので注意してください。★