OSDN Git Service

ECPGの動的SQLの記述をSQLDAを使う場合と区別できる記述にした。
[pghintplan/pg_hint_plan.git] / doc / pg_hint_plan-ja.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <head>
4 <title>pg_hint_plan</title>
5 <!-- Uncoment after the tool has been hosted somewhere.
6 <link rel="home" title="pg_hint_plan" href="index.html">
7 -->
8 <link rel="stylesheet" type="text/css" href="style.css">
9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
10 </head>
11
12 <body>
13 <h1 id="pg_hint_plan">pg_hint_plan 1.0.0</h1>
14 <div class="navigation">
15   <a href="pg_hint_plan-ja.html">pg_hint_plan</a>
16 </div>
17 <hr>
18
19 <div class="index">
20 <ol>
21 <li><a href="#name">pg_hint_planとは?</a></li>
22 <li><a href="#description">機能概要</a></li>
23 <li><a href="#install">インストール</a>
24 <ol>
25   <li><a href="#requirement">動作環境</a></li>
26   <li><a href="#build">ビルド</a></li>
27 </ol>
28 </li>
29 <li><a href="#uninstall">アンインストール</a></li>
30 <li><a href="#usage">使い方</a>
31 <ol>
32   <li><a href="#hint-load">pg_hint_planのロード</a></li>
33   <li><a href="#hint-rule">ヒントの記述方法</a></li>
34   <li><a href="#hint-group">ヒントのグループ</a></li>
35   <li><a href="#hint-GUC">pg_hint_planのGUCパラメータ</a></li>
36 </ol>
37 </li>
38 <li><a href="#restrictions">使用上の注意と制約</a></li>
39 <li><a href="#seealso">関連項目</a></li>
40 <li><a href="hint_list-ja.html">Appendix A. ヒント一覧</a></li>
41 </div>
42
43 <h2 id="name">pg_hint_planとは?</h2>
44 <p>pg_hint_planは、元のSQL文を変えずに実行計画を制御するためのツールです。</p>
45
46 <h2 id="description">機能概要</h2>
47 <p>pg_hint_planを用いると、ヒントを記述したブロックコメントをSQL文の前に加えることで、実行計画を制御することができます。</p>
48
49 <h2 id="install">インストール</h2>
50 <p>pg_hint_planのインストール方法について説明します。</p>
51
52 <h3 id="requirement">動作環境</h3>
53 <dl>
54 <dt>PostgreSQL</dt>
55   <dd>バージョン 9.1.4、9.2.1</dd>
56 <dt>動作検証済みOS</dt>
57   <dd>RHEL 6.1</dd>
58 </dl>
59
60 <h3 id="build">ビルド</h3>
61 <p>pg_hint_planをソースコードからビルドする場合、pg_hint_planのソースを展開したディレクトリでmake → make installの順に実行してください。make installはPostgreSQLをインストールしたOSユーザで実行してください。なお、pg_hint_planのビルドにはpgxsを使用するので、RPM版のPostgreSQLを使用している環境では、postgresql-devel パッケージが必要です。</p>
62 <p>以下にビルドの例を示します。</p>
63 <pre>
64 $ tar xzvf pg_hint_plan-1.0.0.tar.gz
65 $ cd pg_hint_plan-1.0.0
66 $ make
67 $ su
68 # make install
69 </pre>
70
71 <h2 id="uninstall">アンインストール</h2>
72 <p>pg_hint_planをアンインストールするには、pg_hint_planのソースを展開したディレクトリでmake uninstallを実行してください。make uninstallはPostgreSQLをインストールしたOSユーザで実行してください。</p>
73 <p>以下にアンインストールの例を示します。</p>
74 <pre>
75 $ cd pg_hint_plan-1.0.0
76 $ su
77 # make uninstall
78 </pre>
79
80 <h2 id="usage">使い方</h2>
81 <p>pg_hint_planの使い方について説明します。</p>
82
83 <h3 id="hint-load">pg_hint_planのロード</h3>
84 <p>pg_hint_planを使うには、以下の例のようにpg_hint_planの共有ライブラリをロードしてください。全てのセッションでpg_hint_planを有効にするには、shared_preload_libraries GUCパラメータに'pg_hint_plan'を追加してからサーバを再起動して下さい。</p>
85 <pre>
86 postgres=# LOAD 'pg_hint_plan';
87 LOAD
88 postgres=# </pre>
89
90 <h3 id="hint-rule">ヒントの記述方法</h3>
91 <p>ヒントはクエリ文字列の先頭のブロックコメント内に記述してください。ブロックコメントをヒントとして認識させるには、ブロックコメントの開始直後にプラス(+)を指定する必要があります。ヒントの対象は、カッコ内にオブジェクト名または別名(別名)で指定してください。オブジェクト名は、スペース、タブ、または改行のいずれかで区切って指定してください。</p>
92
93 <p>以下の例では、HashJoinとSeqScanヒントにより、pgbench_accountsテーブルに対するSeq Scanの結果をHash Joinする実行計画が選択されています。</p>
94 <pre>
95 postgres=# /*+
96 postgres*#    <span class="strong">HashJoin(a b)</span>
97 postgres*#    <span class="strong">SeqScan(a)</span>
98 postgres*#  */
99 postgres-# EXPLAIN SELECT *
100 postgres-#    FROM pgbench_branches b
101 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
102 postgres-#   ORDER BY a.aid;
103                                       QUERY PLAN
104 ---------------------------------------------------------------------------------------
105  Sort  (cost=31465.84..31715.84 rows=100000 width=197)
106    Sort Key: a.aid
107    ->  <span class="strong">Hash Join</span>  (cost=1.02..4016.02 rows=100000 width=197)
108          Hash Cond: (a.bid = b.bid)
109          ->  <span class="strong">Seq Scan on pgbench_accounts a</span>  (cost=0.00..2640.00 rows=100000 width=97)
110          ->  Hash  (cost=1.01..1.01 rows=1 width=100)
111                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
112 (7 rows)
113
114 postgres=# </pre>
115
116 <h3 id="hint-group">ヒントのグループ</h3>
117 <p>pg_hint_planで使えるヒントは、スキャン方式と結合方式、結合順序、GUCパラメータの4グループに分けられます。各グループの具体的なヒントは、<a href="hint_list-ja.html">ヒント一覧</a>を参照してください。</p>
118
119 <h4>スキャン方式</h4>
120 <p>あるオブジェクトでどのスキャン方式を選択するかを指定できるヒントのグループで、「SeqScan」や「IndexScan」などが含まれます。</p>
121 <p>スキャン方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、システムカタログです。スキャン方式を指定できないオブジェクトは、外部テーブル、テーブル関数、VALUESコマンド結果、CTE、ビュー、副問い合わせ結果です。</p>
122 <p>特定のオブジェクトについてあるスキャン方式を選択して欲しい場合は、そのスキャン方式のヒントと、対象となるオブジェクトの名前を指定してください。逆に、特定のオブジェクトについてあるスキャン方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じオブジェクトに対して複数のスキャン方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
123
124 <h4>結合方式</h4>
125 <p>あるオブジェクトの組み合わせでどの結合方式を選択するかを指定できるヒントのグループで、「MergeJoin」や「NestLoop」などが含まれます。</p>
126 <p>結合方式を指定できるオブジェクトは、通常のテーブル、継承テーブル、UNLOGGEDテーブル、一時テーブル、外部テーブル、システムカタログ、テーブル関数、VALUESコマンド結果、CTEです。結合方式を指定できないオブジェクトは、ビュー、副問い合わせ結果です。</p>
127 <p>特定のオブジェクトの組み合わせについてある結合方式を選択して欲しい場合は、その結合方式のヒントと、対象となる2つ以上のオブジェクトの名前を指定してください。逆に、特定のオブジェクトの組み合わせについてある結合方式を選択して欲しくない場合は、Noで始まるヒントを指定してください。同じオブジェクトの組み合わせに対して複数の結合方式のヒントを指定した場合は、最後に指定したヒントが適用されます。</p>
128 <h4>結合順序</h4>
129 <p>あるオブジェクトの組み合わせでどのような順番で結合するかを指定できるヒントのグループで、「Leading」のみが含まれます。</p>
130 <p>結合順序を指定できるオブジェクトは結合方式と同じです。</p>
131 <p>先に結合して欲しいオブジェクトから順にオブジェクト名または別名を指定してください。複数の結合順序のヒントを指定した場合は、最後に指定したヒントが適用されます。クエリ中に複数の問い合わせブロックがあり、それぞれに結合順を指定したい場合は、それぞれの結合順を1つのLeadingヒントに連続して指定してください。</p>
132 <h4>GUCパラメータ</h4>
133 <p>そのクエリの実行計画を作成している間だけGUCパラメータを変更できるヒントのグループで、「Set」のみが含まれます。</p>
134 <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>
135 <p>Setヒントに<a href="#hint-GUC">pg_hint_planのGUCパラメータ</a>を指定することはできますが、期待通りの動作をしないため、指定しないことをおすすめします。指定した場合の実際の動作は、<a href="#restrictions">使用上の注意と制約</a>を参照してください。</p>
136
137 <h3 id="hint-GUC">pg_hint_planのGUCパラメータ</h3>
138 <p>pg_hint_planの動作を制御するGUCパラメータを以下に記述します。</p>
139 <table>
140 <thead>
141 <tr>
142 <tr><th>GUCパラメータ</th><th>説明</th><th>デフォルト値</th></tr>
143 </tr></thead>
144 <tbody>
145 <tr><td>pg_hint_plan.enable_hint</td>
146   <td>pg_hint_planの機能を有効または無効にします。</td><td>on</td></tr>
147 <tr><td>pg_hint_plan.debug_print</td>
148   <td>pg_hint_planのデバッグ出力を有効にします。メッセージはLOGメッセージレベルで出力されますので、デフォルトではサーバログに出力され、クライアントには渡されません。</td><td>off</td></tr>
149 <tr><td>pg_hint_plan.parse_messages</td>
150   <td>指定したヒントを解釈できなかった場合に、どのメッセージ階層でログを出力するかを指定します。有効な値は、debug5、debug4、debug3、debug2、debug1、log、info、notice、warning、またはerrorです。fatalとpanicは指定できません。</td><td>info</td></tr>
151 </tbody>
152 </table>
153 <p>
154 PostgreSQL 9.1の環境でこれらのパラメータをpostgresql.confファイルで設定するには、<a href="http://www.postgresql.org/docs/9.1/static/runtime-config-custom.html#GUC-CUSTOM-VARIABLE-CLASSES">custom_variable_classes</a>にpg_hint_planを加える必要があります。
155 典型的な使用例は以下のようになります。
156 </p>
157 <pre>
158 # postgresql.conf
159 shared_preload_libraries = 'pg_hint_plan'
160
161 custom_variable_classes = 'pg_hint_plan'    # 9.2以降は廃止されたため記述不要
162 pg_hint_plan.parse_messages = 'debug2'
163 </pre>
164 <p>
165 PostgreSQL 9.2以降ではcustom_variable_classesは廃止されているため、pg_hint_planのGUCパラメータを標準のGUCパラメータと同様に記述することができます。
166 </p>
167
168 <h2 id="restrictions">使用上の注意と制約</h2>
169 <p>pg_hint_planを使用する際には、以下の注意と制約があります。</p>
170 <h3>ヒントの指定方法</h3>
171 <dl>
172 <dt>ヒントの記述位置</dt>
173 <dd>クエリの前に複数のブロックコメントを記述する場合は、最初のブロックコメントにのみヒントを記述してください。二番目以降のブロックコメントは、ヒントと見なされず無視されます。以下の例では、HashJoin(a b)とSeqScan(a)がヒントと見なされ、IndexScan(a)とMergeJoin(a b)は無視されています。</p>
174 <pre>
175 postgres=# /*+
176 postgres*#    <span class="strong">HashJoin(a b)</span>
177 postgres*#    <span class="strong">SeqScan(a)</span>
178 postgres*#  */
179 postgres-# /*+ IndexScan(a) */
180 postgres-# EXPLAIN SELECT /*+ MergeJoin(a b) */ *
181 postgres-#    FROM pgbench_branches b
182 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
183 postgres-#   ORDER BY a.aid;
184                                       QUERY PLAN
185 ---------------------------------------------------------------------------------------
186  Sort  (cost=31465.84..31715.84 rows=100000 width=197)
187    Sort Key: a.aid
188    ->  <span class="strong">Hash Join</span>  (cost=1.02..4016.02 rows=100000 width=197)
189          Hash Cond: (a.bid = b.bid)
190          ->  <span class="strong">Seq Scan on pgbench_accounts a</span>  (cost=0.00..2640.00 rows=100000 width=97)
191          ->  Hash  (cost=1.01..1.01 rows=1 width=100)
192                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
193 (7 rows)
194
195 postgres=# </pre>
196 </dd>
197 <dt>オブジェクト名の引用符付け</dt>
198 <dd>ヒントに記述するオブジェクト名や別名が閉じ括弧())、二重引用符(")、空白(スペース、タブ、改行のいずれか)を含む場合は、通常のSQL文で使う場合と同じように二重引用符(")で囲んでください。二重引用符を含むオブジェクト名は、二重引用符で括ったうえで二重引用符を二重引用符でエスケープしてください(例: 「quoted"table"name」→「"quoted""table""name"」)。</dd>
199 <dt>同一名称テーブルの区別</dt>
200 <dd>スキーマ違いや同一テーブルの複数回使用などでクエリ中に同一名称のテーブルが複数回出現する場合は、テーブルに別名をつけてそれぞれのテーブルを区別してください。以下の例の1つ目のSQL文では、HashJoin(t1 t1)をヒントに指定したとき、ヒント対象のオブジェクトが特定できずにエラーになっています。2つ目のSQL文では、各テーブルにptやstという別名をつけているため、実行計画作成時にヒントで指定した通りにHash Joinを選択しています。</p>
201 <pre>
202 postgres=# /*+ <span class="strong">HashJoin(t1 t1)</span>*/
203 postgres-# EXPLAIN SELECT * FROM s1.t1
204 postgres-# JOIN public.t1 ON (s1.t1.id=public.t1.id);
205 INFO:  hint syntax error at or near "HashJoin(t1 t1)"
206 <span class="strong">DETAIL:  Relation name "t1" is ambiguous.</span>
207                             QUERY PLAN
208 ------------------------------------------------------------------
209  Merge Join  (cost=337.49..781.49 rows=28800 width=8)
210    Merge Cond: (s1.t1.id = public.t1.id)
211    ->  Sort  (cost=168.75..174.75 rows=2400 width=4)
212          Sort Key: s1.t1.id
213          ->  Seq Scan on t1  (cost=0.00..34.00 rows=2400 width=4)
214    ->  Sort  (cost=168.75..174.75 rows=2400 width=4)
215          Sort Key: public.t1.id
216          ->  Seq Scan on t1  (cost=0.00..34.00 rows=2400 width=4)
217 (8 行)
218
219 postgres=# /*+ <span class="strong">HashJoin(pt st)</span> */
220 postgres-# EXPLAIN SELECT * FROM s1.t1 st
221 postgres-# JOIN public.t1 pt ON (st.id=pt.id);
222                              QUERY PLAN
223 ---------------------------------------------------------------------
224  <span class="strong">Hash Join</span>  (cost=64.00..1112.00 rows=28800 width=8)
225    Hash Cond: (st.id = pt.id)
226    ->  Seq Scan on t1 st  (cost=0.00..34.00 rows=2400 width=4)
227    ->  Hash  (cost=34.00..34.00 rows=2400 width=4)
228          ->  Seq Scan on t1 pt  (cost=0.00..34.00 rows=2400 width=4)
229 (5 行)
230
231 postgres=#</pre>
232 </p>
233 </dd>
234 <dt>FROM句にVALUESコマンドを指定した場合の制限</dt>
235 <dd>FROM句にVALUESコマンドを指定した場合は、ヒントのオブジェクト名に「*VALUES*」を指定してください。これは、VALUESの結果に別名を指定しても、PostgreSQL本体側で「*VALUES*」に名称が置き換えられるためです。このため、複数のVALUESを使用する場合は、ヒントの対象を特定できないため、実行計画を制御できません。</dd>
236 </dl>
237 <h3>ヒントの適用対象の指定</h3>
238 <dl>
239 <dt>クエリに明記されていないテーブルへのヒント適用</dt>
240 <dd>ヒントで指定した名称と一致すれば、ビュー定義や関数内クエリなどに出現するテーブルについても、ヒントを指定したクエリ内と同じようにヒントが適用されます。このため、ヒントの適用有無や適用するヒントをそれぞれのテーブルで変えたい場合は、別の別名を指定してください。</br>
241 以下の例では、ビュー定義で使われている「t1」という別名をSeqScanヒントで指定したことで、表スキャンとビュー経由のスキャンの両方でSeq Scanが選択されています。ビュー定義で使用されている「t1」とは別の別名を実表に指定することで、個別にスキャン方式を制御できます。
242 <pre>
243 postgres=# CREATE VIEW view1 AS SELECT * FROM table1 <span class="strong">t1</span>;
244 CREATE TABLE
245 postgres=# /*+ SeqScan(<span class="strong">t1</span>) */
246 postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t1</span> JOIN view1 t2 ON (t1.key = t2.key) WHERE t2.key = 1;
247                            QUERY PLAN
248 -----------------------------------------------------------------
249  Nested Loop  (cost=0.00..358.01 rows=1 width=16)
250    ->  Seq Scan on table1 <span class="strong">t1</span>  (cost=0.00..179.00 rows=1 width=8)
251          Filter: (key = 1)
252    ->  Seq Scan on table1 <span class="strong">t1</span>  (cost=0.00..179.00 rows=1 width=8)
253          Filter: (key = 1)
254 (5 rows)
255
256 postgres=# /*+ SeqScan(<span class="strong">t3</span>) */
257 postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t3</span> JOIN view1 t2 ON (t1.key = t2.key) WHERE t2.key = 1;
258                                    QUERY PLAN
259 --------------------------------------------------------------------------------
260  Nested Loop  (cost=0.00..187.29 rows=1 width=16)
261    ->  Seq Scan on table1 <span class="strong">t3</span>  (cost=0.00..179.00 rows=1 width=8)
262          Filter: (key = 1)
263    ->  Index Scan using foo_pkey on table1 t1  (cost=0.00..8.28 rows=1 width=8)
264          Index Cond: (key = 1)
265 (5 rows)
266
267 </pre>
268 </dd>
269 <dt>継承テーブルに対するヒント</dt>
270 <dd>継承テーブルにスキャン方式のヒントを指定する場合は、オブジェクト名として親テーブルの名称または別名を指定してください。全ての子テーブルに同じスキャン方式を選択します。子テーブルごとに別のスキャン方式を指定することはできません。</dd>
271 <dt>ビューやルールを使うクエリのヒント</dt>
272 <dd>ルールを定義したテーブルやビューを複数用いるときに、各ビュー内のテーブルの別名やルール書き換え後のクエリのテーブルの別名が重複した場合は、ヒントの対象を区別できません。区別する場合は、各ビュー内のテーブルの別名やルール書き換え後のクエリのテーブルの別名を重複させないでください。</dd>
273 <dt>ルールを使うクエリでのヒントの適用範囲</dt>
274 <dd>ルールによるクエリ書き換え後によってクエリが複数になる場合は、先頭のブロックコメントで指定したヒントを全てのクエリで使用します。</dd>
275 <dt>マルチステートメントでのヒントの適用範囲</dt>
276 <dd>クエリがマルチステートメントで実行される場合は、先頭のブロックコメントで指定したヒントを全てのクエリで使用します。2つ目以降のクエリに指定したヒントは無視します。psqlコマンドで-cオプションで複数のクエリを指定した場合などにマルチステートメントで実行されます。</dd>
277 <dt>IndexOnlyScanヒントの指定(PostgreSQL 9.2以降)</dt>
278 <dd>IndexOnlyScanヒントを指定しても、ヒント対象となるテーブルに複数のインデックスが存在するときは、Index Scanが選択される場合があります。この場合は、IndexOnlyScanヒントに、テーブルだけでなくそのテーブルでIndex Only Scanを選択できるインデックスも指定してください。そのインデックスを使ったIndex Only Scanが選択されます。</dd>
279 <dt>NoIndexScanヒントの注意点(PostgreSQL 9.2以降)</dt>
280 <dd>PostgreSQL 9.2以降でNoIndexScanヒントを指定した場合は、Index ScanだけでなくIndex Only Scanも選択されません。</dd>
281 </dl>
282
283 <h3>ヒント指定エラーの扱い</h3>
284 <dt>構文エラー</dt>
285 <dd>ヒントの記述に構文上の誤りがあった場合、pg_hint_planは誤った記述より前のヒントのみ有効とし、誤った記述以降のヒントを無視してクエリを実行します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。
286 <ul>
287 <li>ヒント名が間違っている。</li>
288 <li>オブジェクト指定が正しく括弧で囲まれていない。</li>
289 <li>オブジェクト名が空白で区切られていない。</li>
290 </ul>
291 </dd>
292 <dt>オブジェクト指定エラー</dt>
293 <dd>pg_hint_planは、ヒント対象のオブジェクト指定に誤りがあった場合、pg_hint_planは不正なヒントのみを無視し、それ以外のヒントを使ってっクエリを実行します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。誤ったオブジェクト指定の例を以下に示します。</dd>
294 <ul>
295 <li>クエリ中に同じ名称のテーブル名または別名のテーブルがあり、それに対してヒントを指定した。</li>
296 <li>結合方式や結合順のヒントに同じオブジェクト名を複数回指定した。</li>
297 </ul>
298 </dd>
299 <dt>指定するヒントの種類の重複</dt>
300 <dd>同じオブジェクトに対して同じグループのヒントを重複して指定した場合は、各グループで最後に指定したヒントを使用します。</dd>
301 <dt>ネストしたブロックコメント</dt>
302 <dd>pg_hint_planでは、ヒントを指定したブロックコメントにネストしたブロックコメントを含めることができません。ネストしたブロックコメントを含めた場合は、誤った記述に関する情報を出力しますがエラー終了しません。全てのヒントを無視してクエリを実行します。</dd>
303 <dt>メッセージの出力レベル</dt>
304 <dd>ヒントに誤りがあった場合に出力されるメッセージのレベルは、基本的にはpg_hint_plan.parse_messagesに指定したレベルです。ただし、ヒントに指定したオブジェクトの長さが識別子の最大長(デフォルトでは63バイト)を超えた際に切り詰めた場合は、NOTICEで出力します。</dd>
305
306 <h3>機能制限</h3>
307 <dt>標準のGUCパラメータの影響</dt>
308 <dd>FROMリストの数がfrom_collapse_limitの設定値以上の場合、またはFROMリストの数がjoin_collapse_limitの設定値より大きい場合は、結合順序のヒントが無視されます。また、FROMリストの数がgeqo_thresholdの設定値以上の場合は、結合順序のヒント、および結合方式のヒントが無視されます。ヒントが使われるようにするには、これらのGUCパラメータの値を大きくしてください。</dd>
309 <dt>ヒントで制御できないケース</dt>
310 <dd>pg_hint_planでは、PostgreSQLのプランナが候補としてあげる事ができない実行計画をヒントに指定しても、その実行計画を生成することはできません。PostgreSQLのプランナが候補としてあげる事ができない実行計画の例を以下に示します。
311 <ul>
312 <li>FULL OUTER JOINではNested Loopは候補パスとして扱われません。</li>
313 <li>WHERE句やJOIN条件などに指定されない列のみを含むインデックスは候補パスとして扱われません。</li>
314 <li>検索条件にctidを指定しない場合はTid Scanは候補パスとして扱われません。</li>
315 </ul>
316 </dd>
317 <dt>PL/pgSQLにおける制限</dt>
318 <dd>PL/pgSQLでユーザ定義関数を実装する際に、関数定義内の各クエリの先頭にヒントを指定したとしても、そのヒントは無視します。ユーザ定義関数を実行するSELECTコマンドに指定したヒントを使用します。ただし、PL/pgSQLでは、関数定義内で指定したクエリがそのまま実行されるとは限らないため、ヒントを指定した場合の挙動は保証できません。</dd>
319 <dt>ECPGにおける制限</dt>
320 <dd>pg_hint_planでは、ECPGで実装したアプリケーションから発行するクエリは、基本的に実行計画を制御できません。これは、CプリプロセッサがCコードに変換するタイミングで、全てのブロックコメントを取り除いてしまうためです。ただし、C言語文字列に格納したクエリをEXECUTEコマンドで実行する動的SQLの場合は、クエリ文字列の先頭にヒントを指定することで実行計画を制御できます。</dd>
321 <dt>psqlのフェッチ件数指定</dt>
322 <dd>psqlコマンドのFETCH_COUNT変数に0より大きな整数値を指定すると、pg_hint_planでは実行計画を制御できなくなります。FETCH_COUNT変数に0より大きな整数値を指定すると、ユーザが指定したクエリの先頭に「DECLARE _psql_cursor NO SCROLL CURSOR FOR」が自動的に追加されてクエリが発行されることにより、ヒントがクエリの先頭ではなくなってしまうためです。</dd>
323 <dt>ヒントによるフィンガープリントの変化</dt>
324 <dd>pg_hint_planはSQLコメントでヒントを指定するため、SQL文フィンガープリントベースのクエリキャッシュなどでは、ヒントが異なれば別のSQL文として扱われます。pg_stat_statementも9.1では別クエリとして集計しますが、9.2ではクエリ集約機能によりコメントが除去されるので、ヒントのみが異なるクエリは同じクエリとして扱われます。</dd>
325 <pre>
326 postgres=# /*+ <span class="strong">MergeJoin(a *VALUES*)</span> */
327 postgres-# EXPLAIN SELECT *
328 postgres-#    FROM pgbench_accounts a
329 postgres-#    JOIN (VALUES (1,1),(2,2)) <span class="strong">v</span> (vid, vbalance) ON a.aid = v.vid
330 postgres-#   ORDER BY a.aid;
331                                                   QUERY PLAN
332 ---------------------------------------------------------------------------------------------------------------
333  <span class="strong">Merge Join</span>  (cost=0.04..4497.33 rows=2 width=105)
334    Merge Cond: (a.aid = "*VALUES*".column1)
335    ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a  (cost=0.00..4247.26 rows=100000 width=97)
336    ->  Sort  (cost=0.04..0.04 rows=2 width=8)
337          Sort Key: "*VALUES*".column1
338          ->  Values Scan on <span class="strong">"*VALUES*"</span>  (cost=0.00..0.03 rows=2 width=8)
339 (6 行)
340
341 postgres=#</pre>
342 <dt>Setヒントの制限</dt>
343 <dd>Setヒントに<a href="#hint-GUC">pg_hint_planのGUCパラメータ</a>を指定することはできますが、期待通りの動作をしないため、指定しないことをおすすめします。指定した場合の実際の動作を、以下に示します。
344 <ul>
345 <li>pg_hint_plan.enable_hintおよびpg_hint_plan.debug_printを指定した場合は、無視されます。</li>
346 <li>pg_hint_plan.parse_messagesを指定した場合は、構文エラーと一部のSetヒントのエラーについてはクエリ開始時の設定レベルで出力され、それ以外のメッセージについてはSetヒントで指定したレベルで出力されます。</li>
347 </ul>
348 </dd>
349
350 </dl>
351
352 <h2 id="seealso">関連項目</h2>
353 <h3 id="postgresql_document">PostgreSQLドキュメント</h3>
354 <a href="http://www.postgresql.org/docs/9.1/static/sql-explain.html">EXPLAIN</a>
355 <a href="http://www.postgresql.org/docs/9.1/static/sql-set.html">SET</a>
356 <a href="http://www.postgresql.org/docs/9.1/static/runtime-config.html">サーバの設定</a>
357 <hr>
358
359 <div class="navigation">
360   <a href="pg_hint_plan-ja.html">pg_hint_plan</a>
361 </div>
362
363 <p class="footer">Copyright (c) 2012, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
364
365 <!--
366 <script type="text/javascript">
367 var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
368 document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
369 </script><script src="pg_statsinfo-ja_files/ga.js" type="text/javascript"></script>
370 <script type="text/javascript">
371 try{
372 var pageTracker = _gat._getTracker("UA-10244036-6");
373 pageTracker._trackPageview();
374 } catch(err) {}
375 </script>
376 -->
377 </body>
378 </html>