OSDN Git Service

制約事項が多くなったのでグループに分割
authorShigeru Hanada <shigeru.hanada@gmail.com>
Tue, 18 Dec 2012 03:50:08 +0000 (12:50 +0900)
committerShigeru Hanada <shigeru.hanada@gmail.com>
Tue, 18 Dec 2012 03:50:08 +0000 (12:50 +0900)
併せて用語の統一も行った。
- VIEW、RULE→ビュー、ルール
- エイリアス→別名
レビュー管理表No.6

doc/pg_hint_plan-ja.html

index effaf5e..f47528a 100644 (file)
@@ -88,7 +88,7 @@ LOAD
 postgres=# </pre>
 
 <h3 id="hint-rule">ヒントの記述方法</h3>
-<p>ヒントはクエリ文字列の先頭のブロックコメント内に記述してください。ブロックコメントをヒントとして認識させるには、ブロックコメントの開始直後にプラス(+)を指定する必要があります。ヒントの対象は、カッコ内にオブジェクト名または別名(エイリアス)で指定してください。オブジェクト名は、スペース、タブ、または改行のいずれかで区切って指定してください。</p>
+<p>ヒントはクエリ文字列の先頭のブロックコメント内に記述してください。ブロックコメントをヒントとして認識させるには、ブロックコメントの開始直後にプラス(+)を指定する必要があります。ヒントの対象は、カッコ内にオブジェクト名または別名(別名)で指定してください。オブジェクト名は、スペース、タブ、または改行のいずれかで区切って指定してください。</p>
 
 <p>以下の例では、HashJoinとSeqScanヒントにより、pgbench_accountsテーブルに対するSeq Scanの結果をHash Joinする実行計画が選択されています。</p>
 <pre>
@@ -118,12 +118,12 @@ postgres=# </pre>
 
 <h4>スキャン方式</h4>
 <p>あるオブジェクトでどのスキャン方式を選択するかを指定できるヒントのグループで、「SeqScan」や「IndexScan」などが含まれます。</p>
-<p>スキャン方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、システムカタログです。スキャン方式を指定できないオブジェクトは、外部テーブル、テーブル関数、VALUESコマンド結果、CTE、VIEW、副問い合わせ結果です。</p>
+<p>スキャン方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、システムカタログです。スキャン方式を指定できないオブジェクトは、外部テーブル、テーブル関数、VALUESコマンド結果、CTE、ビュー、副問い合わせ結果です。</p>
 <p>特定のオブジェクトについてあるスキャン方式を選択して欲しい場合は、そのスキャン方式のヒントと、対象となるオブジェクトの名前を指定してください。逆に、特定のオブジェクトについてあるスキャン方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じオブジェクトに対して複数のスキャン方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
 
 <h4>結合方式</h4>
 <p>あるオブジェクトの組み合わせでどの結合方式を選択するかを指定できるヒントのグループで、「MergeJoin」や「NestLoop」などが含まれます。</p>
-<p>結合方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、外部テーブル、システムカタログ、テーブル関数、VALUESコマンド結果、CTEです。結合方式を指定できないオブジェクトは、VIEW、副問い合わせ結果です。</p>
+<p>結合方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、外部テーブル、システムカタログ、テーブル関数、VALUESコマンド結果、CTEです。結合方式を指定できないオブジェクトは、ビュー、副問い合わせ結果です。</p>
 <p>特定のオブジェクトの組み合わせについてある結合方式を選択して欲しい場合は、その結合方式のヒントと、対象となる2つ以上のオブジェクトの名前を指定してください。逆に、特定のオブジェクトの組み合わせについてある結合方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じオブジェクトの組み合わせに対して複数の結合方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
 <h4>結合順序</h4>
 <p>あるオブジェクトの組み合わせでどのような順番で結合するかを指定できるヒントのグループで、「Leading」のみが含まれます。</p>
@@ -167,6 +167,7 @@ PostgreSQL 9.2以降ではcustom_variable_classesは廃止されているため
 
 <h2 id="restrictions">使用上の注意と制約</h2>
 <p>pg_hint_planを使用する際には、以下の注意と制約があります。</p>
+<h3>ヒントの指定方法</h3>
 <dl>
 <dt>ヒントの記述位置</dt>
 <dd>クエリの前に複数のブロックコメントを記述する場合は、最初のブロックコメントにのみヒントを記述してください。二番目以降のブロックコメントは、ヒントと見なされず無視されます。以下の例では、HashJoin(a b)とSeqScan(a)がヒントと見なされ、IndexScan(a)とMergeJoin(a b)は無視されています。</p>
@@ -196,8 +197,7 @@ postgres=# </pre>
 <dt>オブジェクト名の引用符付け</dt>
 <dd>ヒントに記述するオブジェクト名や別名が閉じ括弧())、二重引用符(")、空白(スペース、タブ、改行のいずれか)を含む場合は、通常のSQL文で使う場合と同じように二重引用符(")で囲んでください。二重引用符を含むオブジェクト名は、二重引用符で括ったうえで二重引用符を二重引用符でエスケープしてください(例: 「quoted"table"name」→「"quoted""table""name"」)。</dd>
 <dt>同一名称テーブルの区別</dt>
-<dd>スキーマ違いや同一テーブルの複数回使用などでクエリ中に同一名称のテーブルが複数回出現する場合は、テーブルに別名をつけてそれぞれのテーブルを区別してください。以下の例の1つ目のSQL文では、HashJoin(t1 t1)をヒントに指定したとき、ヒント対象のオブジェクトが特定できずにエラーになっています。2つ目のSQL文では、各テーブルにptやstという別名をつけているため、実行計画作成時にヒントで指定した通りにHash Joinを選択しています。
-</p>
+<dd>スキーマ違いや同一テーブルの複数回使用などでクエリ中に同一名称のテーブルが複数回出現する場合は、テーブルに別名をつけてそれぞれのテーブルを区別してください。以下の例の1つ目のSQL文では、HashJoin(t1 t1)をヒントに指定したとき、ヒント対象のオブジェクトが特定できずにエラーになっています。2つ目のSQL文では、各テーブルにptやstという別名をつけているため、実行計画作成時にヒントで指定した通りにHash Joinを選択しています。</p>
 <pre>
 postgres=# /*+ <span class="strong">HashJoin(t1 t1)</span>*/
 postgres-# EXPLAIN SELECT * FROM s1.t1
@@ -231,36 +231,14 @@ postgres-# JOIN public.t1 pt ON (st.id=pt.id);
 postgres=#</pre>
 </p>
 </dd>
-<dt>ヒントの記述誤り</dt>
-<dd>pg_hint_planでは、ヒントの記述に誤りがあった場合は、誤った記述に関する情報を出力しますがエラー終了しません。誤った記述より前のヒントのみ有効となり、誤った記述以降のヒントを無視してクエリを実行します。</dd>
-<dt>不正なヒント</dt>
-<dd>pg_hint_planでは、不正なヒントの指定があった場合は、不正なヒントに関する情報を出力しますがエラー終了しません。不正なヒントのみ無効となり、その他のヒントは有効なままでクエリを実行します。不正なヒントの例を以下に示します。
-<ul>
-<li>クエリ中に同じ名称のテーブル名または別名のテーブルがあり、それに対してヒントを指定した。</li>
-<li>結合方式のヒント、または結合順のヒントのオブジェクト名に、同じ名称を複数回指定した。</li>
-</ul>
-</dd>
-<dt>ネストしたブロックコメント</dt>
-<dd>pg_hint_planでは、ヒントを指定したブロックコメントにネストしたブロックコメントを含めることができません。ネストしたブロックコメントを含めた場合は、誤った記述に関する情報を出力しますがエラー終了しません。全てのヒントを無視してクエリを実行します。</dd>
-<dt>影響を与えるGUCパラメータ</dt>
-<dd>FROMリストの数がfrom_collapse_limitの設定値以上の場合、またはFROMリストの数がjoin_collapse_limitの設定値より大きい場合は、結合順序のヒントが無視されます。また、FROMリストの数がgeqo_thresholdの設定値以上の場合は、結合順序のヒント、および結合方式のヒントが無視されます。ヒントが使われるようにするには、これらの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>継承テーブルに対する制限</dt>
-<dd>継承テーブルにスキャン方式のヒントを指定する場合は、オブジェクト名として親テーブルの名称または別名を指定してください。全ての子テーブルに同じスキャン方式を選択します。子テーブルごとに別のスキャン方式を指定することはできません。</dd>
-<dt>VIEWおよびRULEに対する制限</dt>
-<dd>VIEWやRULEを定義したテーブルを複数用いるときに、各VIEW内のテーブルの別名やRULE書き換え後のクエリのテーブルの別名が重複した場合は、ヒントの対象を区別できません。区別する場合は、各VIEW内のテーブルの別名やRULE書き換え後のクエリのテーブルの別名を重複させないでください。</dd>
+<dt>FROM句にVALUESコマンドを指定した場合の制限</dt>
+<dd>FROM句にVALUESコマンドを指定した場合は、ヒントのオブジェクト名に「*VALUES*」を指定してください。これは、VALUESの結果に別名を指定しても、PostgreSQL本体側で「*VALUES*」に名称が置き換えられるためです。このため、複数のVALUESを使用する場合は、ヒントの対象を特定できないため、実行計画を制御できません。</dd>
+</dl>
+<h3>ヒントの適用対象の指定</h3>
+<dl>
 <dt>クエリに明記されていないテーブルへのヒント適用</dt>
-<dd>ヒントで指定した名称と一致すれば、VIEW定義や関数内クエリなどに出現するテーブルについても、ヒントを指定したクエリ内と同じようにヒントが適用されます。このため、ヒントの適用有無や適用するヒントをそれぞれのテーブルで変えたい場合は、別のエイリアスを指定してください。</br>
-以下の例では、ビュー定義で使われている「t1」というエイリアスをSeqScanヒントで指定したことで、表スキャンとビュー経由のスキャンの両方でSeq Scanが選択されています。ビュー定義で使用されている「t1」とは別のエイリアスを実表に指定することで、個別にスキャン方式を制御できます。
+<dd>ヒントで指定した名称と一致すれば、ビュー定義や関数内クエリなどに出現するテーブルについても、ヒントを指定したクエリ内と同じようにヒントが適用されます。このため、ヒントの適用有無や適用するヒントをそれぞれのテーブルで変えたい場合は、別の別名を指定してください。</br>
+以下の例では、ビュー定義で使われている「t1」という別名をSeqScanヒントで指定したことで、表スキャンとビュー経由のスキャンの両方でSeq Scanが選択されています。ビュー定義で使用されている「t1」とは別の別名を実表に指定することで、個別にスキャン方式を制御できます。
 <pre>
 postgres=# CREATE VIEW view1 AS SELECT * FROM table1 <span class="strong">t1</span>;
 CREATE TABLE
@@ -288,20 +266,62 @@ postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t3</span> JOIN view
 
 </pre>
 </dd>
-<dt>マルチステートメントにおける制限</dt>
+<dt>継承テーブルに対するヒント</dt>
+<dd>継承テーブルにスキャン方式のヒントを指定する場合は、オブジェクト名として親テーブルの名称または別名を指定してください。全ての子テーブルに同じスキャン方式を選択します。子テーブルごとに別のスキャン方式を指定することはできません。</dd>
+<dt>ビューやルールを使うクエリのヒント</dt>
+<dd>ルールを定義したテーブルやビューを複数用いるときに、各ビュー内のテーブルの別名やルール書き換え後のクエリのテーブルの別名が重複した場合は、ヒントの対象を区別できません。区別する場合は、各ビュー内のテーブルの別名やルール書き換え後のクエリのテーブルの別名を重複させないでください。</dd>
+<dt>ルールを使うクエリでのヒントの適用範囲</dt>
+<dd>ルールによるクエリ書き換え後によってクエリが複数になる場合は、先頭のブロックコメントで指定したヒントを全てのクエリで使用します。</dd>
+<dt>マルチステートメントでのヒントの適用範囲</dt>
 <dd>クエリがマルチステートメントで実行される場合は、先頭のブロックコメントで指定したヒントを全てのクエリで使用します。2つ目以降のクエリに指定したヒントは無視します。psqlコマンドで-cオプションで複数のクエリを指定した場合などにマルチステートメントで実行されます。</dd>
-<dt>RULEにおける制限</dt>
-<dd>RULEによるクエリ書き換え後によってクエリが複数になる場合は、先頭のブロックコメントで指定したヒントを全てのクエリで使用します。</dd>
+<dt>IndexOnlyScanヒントの指定(PostgreSQL 9.2以降)</dt>
+<dd>IndexOnlyScanヒントを指定しても、ヒント対象となるテーブルに複数のインデックスが存在するときは、Index Scanが選択される場合があります。この場合は、IndexOnlyScanヒントに、テーブルだけでなくそのテーブルでIndex Only Scanを選択できるインデックスも指定してください。そのインデックスを使ったIndex Only Scanが選択されます。</dd>
+<dt>NoIndexScanヒントの注意点(PostgreSQL 9.2以降)</dt>
+<dd>PostgreSQL 9.2以降でNoIndexScanヒントを指定した場合は、Index ScanだけでなくIndex Only Scanも選択されません。</dd>
+</dl>
+
+<h3>ヒント指定エラーの扱い</h3>
+<dt>構文エラー</dt>
+<dd>ヒントの記述に構文上の誤りがあった場合、pg_hint_planは誤った記述より前のヒントのみ有効とし、誤った記述以降のヒントを無視してクエリを実行します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。
+<ul>
+<li>ヒント名が間違っている。</li>
+<li>オブジェクト指定が正しく括弧で囲まれていない。</li>
+<li>オブジェクト名が空白で区切られていない。</li>
+</ul>
+</dd>
+<dt>オブジェクト指定エラー</dt>
+<dd>pg_hint_planは、ヒント対象のオブジェクト指定に誤りがあった場合、pg_hint_planは不正なヒントのみを無視し、それ以外のヒントを使ってっクエリを実行します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。誤ったオブジェクト指定の例を以下に示します。</dd>
+<ul>
+<li>クエリ中に同じ名称のテーブル名または別名のテーブルがあり、それに対してヒントを指定した。</li>
+<li>結合方式や結合順のヒントに同じオブジェクト名を複数回指定した。</li>
+</ul>
+</dd>
+<dt>指定するヒントの種類の重複</dt>
+<dd>同じオブジェクトに対して同じグループのヒントを重複して指定した場合は、各グループで最後に指定したヒントを使用します。</dd>
+<dt>ネストしたブロックコメント</dt>
+<dd>pg_hint_planでは、ヒントを指定したブロックコメントにネストしたブロックコメントを含めることができません。ネストしたブロックコメントを含めた場合は、誤った記述に関する情報を出力しますがエラー終了しません。全てのヒントを無視してクエリを実行します。</dd>
+<dt>メッセージの出力レベル</dt>
+<dd>ヒントに誤りがあった場合に出力されるメッセージのレベルは、基本的にはpg_hint_plan.parse_messagesに指定したレベルです。ただし、ヒントに指定したオブジェクトの長さが識別子の最大長(デフォルトでは63バイト)を超えた際に切り詰めた場合は、NOTICEで出力します。</dd>
+
+<h3>機能制限</h3>
+<dt>標準のGUCパラメータの影響</dt>
+<dd>FROMリストの数がfrom_collapse_limitの設定値以上の場合、またはFROMリストの数がjoin_collapse_limitの設定値より大きい場合は、結合順序のヒントが無視されます。また、FROMリストの数がgeqo_thresholdの設定値以上の場合は、結合順序のヒント、および結合方式のヒントが無視されます。ヒントが使われるようにするには、これらのGUCパラメータの値を大きくしてください。</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>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の結果に別名を指定しても、PostgreSQL本体側で「*VALUES*」に名称が置き換えられるためです。このため、複数のVALUESを使用する場合は、ヒントの対象を特定できないため、実行計画を制御できません。</dd>
+<dt>ヒントによるフィンガープリントの変化</dt>
+<dd>pg_hint_planはSQLコメントでヒントを指定するため、SQL文フィンガープリントベースのクエリキャッシュなどでは、ヒントが異なれば別のSQL文として扱われます。pg_stat_statementも9.1では別クエリとして集計しますが、9.2ではクエリ集約機能によりコメントが除去されるので、ヒントのみが異なるクエリは同じクエリとして扱われます。</dd>
 <pre>
 postgres=# /*+ <span class="strong">MergeJoin(a *VALUES*)</span> */
 postgres-# EXPLAIN SELECT *
@@ -326,12 +346,6 @@ postgres=#</pre>
 <li>pg_hint_plan.parse_messagesを指定した場合は、構文エラーと一部のSetヒントのエラーについてはクエリ開始時の設定レベルで出力され、それ以外のメッセージについてはSetヒントで指定したレベルで出力されます。</li>
 </ul>
 </dd>
-<dt>メッセージの出力レベル</dt>
-<dd>ヒントに誤りがあった場合に出力されるメッセージのレベルは、基本的にはpg_hint_plan.parse_messagesに指定したレベルです。ただし、ヒントに指定したオブジェクトの長さが、識別子の最大長(デフォルトでは63バイト)を超えた際に切り詰めた場合は、NOTICEで出力します。</dd>
-<dt>IndexOnlyScanヒントの制限(PostgreSQL 9.2以降)</dt>
-<dd>IndexOnlyScanヒントを指定しても、ヒント対象となるテーブルに複数のインデックスが存在するときは、Index Scanが選択される場合があります。この場合は、IndexOnlyScanヒントに、テーブルだけでなくそのテーブルでIndex Only Scanを選択できるインデックスも指定してください。そのインデックスを使ったIndex Only Scanが選択されます。</dd>
-<dt>NoIndexScanヒントの制限(PostgreSQL 9.2以降)</dt>
-<dd>NoIndexScanヒントを指定した場合は、Index ScanだけでなくIndex Only Scanも選択されません。</dd>
 
 </dl>