OSDN Git Service

使用上の注意と制限を追加した。
authorMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Fri, 13 Jul 2012 12:25:14 +0000 (21:25 +0900)
committerMitsuru Hasegawa <hasegawa@metrosystems.co.jp>
Fri, 13 Jul 2012 12:25:14 +0000 (21:25 +0900)
doc/pg_hint_plan-ja.html

index a69a8c0..e0fad13 100644 (file)
@@ -117,15 +117,18 @@ postgres=# </pre>
 <p>pg_hint_planで使えるヒントは、スキャン方式と結合方式、結合順序、GUCパラメータの4グループに分けられます。各グループの具体的なヒントは、<a href="hint_list-ja.html">ヒント一覧</a>を参照してください。</p>
 
 <h4>スキャン方式</h4>
-<p>あるテーブルでどのスキャン方式を選択するかを指定できるヒントのグループで、「SeqScan」や「IndexScan」などが含まれます。</p>
-<p>特定のテーブルについてあるスキャン方式を選択して欲しい場合は、そのスキャン方式のヒントと、対象となるテーブルの名前を指定してください。逆に、特定のテーブルについてあるスキャン方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じテーブルに対して複数のスキャン方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
+<p>あるオブジェクトでどのスキャン方式を選択するかを指定できるヒントのグループで、「SeqScan」や「IndexScan」などが含まれます。</p>
+<p>スキャン方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、システムカタログです。スキャン方式を指定できないオブジェクトは、外部テーブル、テーブル関数、VALUESコマンド結果、CTE、VIEW、副問い合わせ結果です。</p>
+<p>特定のオブジェクトについてあるスキャン方式を選択して欲しい場合は、そのスキャン方式のヒントと、対象となるオブジェクトの名前を指定してください。逆に、特定のオブジェクトについてあるスキャン方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じオブジェクトに対して複数のスキャン方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
 
 <h4>結合方式</h4>
-<p>あるテーブルの組み合わせでどの結合方式を選択するかを指定できるヒントのグループで、「MergeJoin」や「NestLoop」などが含まれます。</p>
-<p>特定のテーブルの組み合わせについてある結合方式を選択して欲しい場合は、その結合方式のヒントと、対象となる2つ以上のテーブルの名前を指定してください。逆に、特定のテーブルの組み合わせについてある結合方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じテーブルの組み合わせに対して複数の結合方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
+<p>あるオブジェクトの組み合わせでどの結合方式を選択するかを指定できるヒントのグループで、「MergeJoin」や「NestLoop」などが含まれます。</p>
+<p>結合方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、外部テーブル、システムカタログ、テーブル関数、VALUESコマンド結果、CTEです。結合方式を指定できないオブジェクトは、VIEW、副問い合わせ結果です。</p>
+<p>特定のオブジェクトの組み合わせについてある結合方式を選択して欲しい場合は、その結合方式のヒントと、対象となる2つ以上のオブジェクトの名前を指定してください。逆に、特定のオブジェクトの組み合わせについてある結合方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じオブジェクトの組み合わせに対して複数の結合方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
 <h4>結合順序</h4>
-<p>あるテーブルの組み合わせでどのような順番で結合するかを指定できるヒントのグループで、「Leading」のみが含まれます。</p>
-<p>先に結合して欲しいテーブルから順にテーブル名または別名を指定してください。複数の結合順序のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
+<p>あるオブジェクトの組み合わせでどのような順番で結合するかを指定できるヒントのグループで、「Leading」のみが含まれます。</p>
+<p>結合順序を指定できるオブジェクトは結合方式と同じです。</p>
+<p>先に結合して欲しいオブジェクトから順にオブジェクト名または別名を指定してください。複数の結合順序のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
 <h4>GUCパラメータ</h4>
 <p>そのクエリの実行計画を作成している間だけGUCパラメータを変更できるヒントのグループで、「Set」のみが含まれます。</p>
 <p>設定したいGUCパラメータとそのパラメータの値を指定してください。<a href="http://www.postgresql.org/docs/9.1/static/sql-set.html">SET</a>コマンドで指定できるGUCパラメータならば全て指定できますが、効果があるのは<a href="http://www.postgresql.org/docs/9.1/static/runtime-config-query.html">問い合わせ計画</a>のGUCパラメータのみです。同じGUCパラメータに対して複数のGUCパラメータのヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
@@ -220,12 +223,63 @@ postgres=#</pre>
 </dd>
 <dt>ヒントの記述誤り</dt>
 <dd>pg_hint_planでは、ヒントの記述に誤りがあった場合は、誤った記述に関する情報を出力しますがエラー終了しません。誤った記述より前のヒントのみ有効となり、誤った記述以降のヒントを無視してクエリを実行します。</dd>
+<dt>不正なヒント</dt>
+<dd>pg_hint_planでは、不正なヒントの指定があった場合は、不正なヒントに関する情報を出力しますがエラー終了しません。不正なヒントのみ無効となり、その他のヒントは有効なままでクエリを実行します。不正なヒントの例を以下に示します。
+<ul>
+<li>クエリ中に同じ名称のテーブル名または別名のテーブルがあり、それに対してヒントを指定した。</li>
+<li>結合方式のヒント、または結合順のヒントのオブジェクト名に、同じ名称を複数回指定した。</li>
+</ul>
+</dd>
+<dt>影響を与えるGUCパラメータ</dt>
+<dd>geqo_threshold、from_collapse_limit、およびjoin_collapse_limitによって結合順序が決定する場合は、結合順序のヒントより優先されます。GUCパラメータより結合順序のヒントを優先するには、GUCパラメータの値を結合対象のテーブル数より大きくしてください。</dd>
 <dt>指定するヒントの種類の重複</dt>
 <dd>同じオブジェクトに対して同じグループのヒントを重複して指定した場合は、最後に指定したヒントを使用します。</dd>
+<dt>制御可能なヒントの制限</dt>
+<dd>pg_hint_planでは、PostgreSQLのプランナが候補としてあげる事ができない実行計画をヒントに指定しても、その実行計画を生成することはできません。PostgreSQLのプランナが候補としてあげる事ができない実行計画の例を以下に示します。
+<ul>
+<li>FULL OUTER JOINではNested Loopは候補パスとして扱われません。</li>
+<li>WHERE句やJOIN条件などに指定されない列のみを含むインデックスは候補パスとして扱われません。</li>
+<li>>検索条件にctidを指定しない場合はTid Scanは候補パスとして扱われません。</li>
+</ul>
+</dd>
 <dt>PREPARE/EXECUTEに対する制限</dt>
 <dd>libpqプロトコルの拡張問い合わせプロトコルを使い、かつSQL文をPREPARE文とEXECUTE文で実行する場合は、pg_hint_planでは実行計画を制御できません。拡張問い合わせプロトコルで準備された文を使用したい場合は、各種ライブラリが用意しているプリペアド機能を使用してください。例えば、JDBCではクエリの実行に常に拡張問い合わせプロトコルが使われるため、準備した文が必要な場合はPreparedStatementを使用する必要があります。</dd>
-<dt>ビューに対する制限</dt>
-<dd>ビューを複数用いるときに、各ビュー内のテーブルの別名が重複した場合は、ヒントの対象を区別できません。区別する場合は、各ビュー内のテーブルの別名を重複させないでください。</dd>
+<dt>継承テーブルに対する制限</dt>
+<dd>継承テーブルにスキャン方式のヒントを指定する場合は、オブジェクト名として親テーブルの名称または別名を指定してください。全ての子テーブルに同じスキャン方式を選択します。子テーブルごとに別のスキャン方式を指定することはできません。</dd>
+<dt>VIEWおよびRULEに対する制限</dt>
+<dd>VIEWやRULEを定義したテーブルを複数用いるときに、各VIEW内のテーブルの別名やRULE書き換え後のクエリのテーブルの別名が重複した場合は、ヒントの対象を区別できません。区別する場合は、各VIEW内のテーブルの別名やRULE書き換え後のクエリのテーブルの別名を重複させないでください。</dd>
+<dt>マルチステートメントにおける制限</dt>
+<dd>クエリがマルチステートメントで実行される場合は、先頭のコメントで指定したヒントを全てのクエリで使用します。2つ目以降のクエリに指定したヒントは無視します。psqlコマンドで-cオプションで複数のクエリを指定した場合などにマルチステートメントで実行されます。</dd>
+<dt>RULEにおける制限</dt>
+<dd>RULEによるクエリ書き換え後によってクエリが複数になる場合は、先頭のコメントで指定したヒントを全てのクエリで使用します。</dd>
+<dt>PL/pgSQLおける制限</dt>
+<dd>PL/pgSQLでユーザ定義関数を実装する際に、関数定義内の各クエリの先頭にヒントを指定したとしても、そのヒントは無視します。ユーザ定義関数を実行するSELECTコマンドに指定したヒントを使用します。ただし、PL/pgSQLでは、関数定義内で指定したクエリがそのまま実行されるとは限らないため、ヒントを指定した場合の挙動は保証できません。</dd>
+<dt>ECPGにおける制限</dt>
+<dd>pg_hint_planでは、ECPGで実装したアプリケーションから発行するクエリは、基本的に実行計画を制御できません。これは、CプリプロセッサがCコードに変換するタイミングで、全てのコメントを取り除いてしまうためです。ECPGでも例外的に、動的SQLの先頭にヒントを指定した場合は、実行計画を制御できます。</dd>
+<dt>psqlのフェッチ件数指定</dt>
+<dd>psqlコマンドのFETCH_COUNT変数に0より大きな整数値を指定すると、pg_hint_planでは実行計画を制御できなくなります。FETCH_COUNT変数に0より大きな整数値を指定すると、ユーザが指定したクエリの先頭に「DECLARE _psql_cursor NO SCROLL CURSOR FOR」が自動的に追加されてクエリが発行されることにより、ヒントがクエリの先頭ではなくなってしまうためです。</dd>
+<dt>ヒントによる他の機能への影響</dt>
+<dd>pg_stat_statementやSQL文フィンガープリントベースのクエリキャッシュなどでは、ヒントが異なれば別のSQL文として扱われます。</dd>
+<dt>FROM句にVALUESコマンドを指定した場合の制限</dt>
+<dd>FROM句にVALUESコマンドを指定した場合は、ヒントのオブジェクト名に「*VALUES*」を指定してください。これは、VALUESの結果に別名を指定しても、内部的に「*VALUES*」に名称が置き換えられるためです。このため、複数のVALUESを指定するとヒントの対象を特定できなくなり、実行計画を制御できません。</dd>
+<pre>
+postgres=# /* <span class="strong">MergeJoin(a *VALUES*)</span> */
+postgres-# EXPLAIN SELECT *
+postgres-#    FROM pgbench_accounts a
+postgres-#    JOIN (VALUES (1,1),(2,2)) v (vid, vbalance) ON a.aid = v.vid
+postgres-#   ORDER BY a.aid;
+                                                 QUERY PLAN
+-------------------------------------------------------------------------------------------------------------
+ Sort  (cost=16.62..16.62 rows=2 width=105)
+   Sort Key: a.aid
+   ->  <span class="strong">Nested Loop</span>  (cost=0.00..16.61 rows=2 width=105)
+         ->  Values Scan on <span class="strong">"*VALUES*"</span>  (cost=0.00..0.03 rows=2 width=8)
+         ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a  (cost=0.00..8.28 rows=1 width=97)
+               Index Cond: (aid = "*VALUES*".column1)
+(6 行)
+
+postgres=#</pre>
+
 </dl>
 
 <h2 id="seealso">関連項目</h2>