OSDN Git Service

7b67468d35adc195df08c55d00068ba12df83430
[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 0.1.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-type">ヒントのグループ</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="#known-issues">既知の問題</a></li>
40 <li><a href="#seealso">関連項目</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.3</dd>
56   <dd>バージョン 9.2devel 4月2日版</dd>
57 <dt>動作検証済みOS</dt><dd>RHEL 6.1</dd>
58 </dl>
59
60 <h3 id="build">ビルド</h3>
61 <p>pg_hint_planをソースコードからビルドする場合、pg_hint_planのソースを展開したディレクトリでmake → make installの順に実行してください。なお、pg_hint_planのビルドにはpgxsを使用するので、RPM版のPostgreSQLを使用している環境では、postgresql-devel パッケージが必要です。</p>
62 <p>以下にビルドの例を示します。</p>
63 <pre>
64 $ tar xzvf pg_hint_plan-0.1.0.tar.gz
65 $ cd pg_hint_plan-0.1.0
66 $ make
67 $ make install
68 </pre>
69
70 <h2 id="uninstall">アンインストール</h2>
71 <p>pg_hint_planをアンインストールするには、pg_hint_planのソースを展開したディレクトリでmake uninstallを実行してください。</p>
72 <p>以下にアンインストールの例を示します。</p>
73 <pre>
74 $ cd pg_hint_plan-0.1.0
75 $ make uninstall
76 </pre>
77
78 <h2 id="usage">使い方</h2>
79 <p>pg_hint_planの使い方について説明します。</p>
80
81 <h3 id="hint-load">pg_hint_planのロード</h3>
82 <p>pg_hint_planを使うには、以下の例のようにpg_hint_planの共有ライブラリをロードしてください。全てのセッションでpg_hint_planを有効にするには、shared_preload_librariesに'pg_hint_plan'を追加して下さい。</p>
83 <pre>
84 postgres=# LOAD 'pg_hint_plan';
85 LOAD
86 postgres=# </pre>
87
88 <h3 id="hint-rule">ヒントの記述方法</h3>
89 <p>ヒントはクエリの前のブロックコメント内に、スペース、タブまたは改行のいずれかで区切って記述してください。ヒントの対象がテーブルの場合は、テーブル名または別名(エイリアス)で指定してください。ただし、スキーマが異なる同じ名前のテーブルを1クエリ中に用いる場合は、別名で指定してください。これは、クエリ中の特定のテーブルを指定できるようにするためです。</p>
90
91 <p>以下の例では、HashJoinとSeqScanヒントにより、pgbench_accountsテーブルに対するSeq Scanの結果をHash Joinする実行計画が選択されています。</p>
92 <pre>
93 postgres=# /*
94 postgres*#    <span class="strong">HashJoin(a b)</span>
95 postgres*#    <span class="strong">SeqScan(a)</span>
96 postgres*#  */
97 postgres-# EXPLAIN SELECT *
98 postgres-#    FROM pgbench_branches b
99 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
100 postgres-#   ORDER BY a.aid;
101                                       QUERY PLAN
102 ---------------------------------------------------------------------------------------
103  Sort  (cost=31465.84..31715.84 rows=100000 width=197)
104    Sort Key: a.aid
105    ->  <span class="strong">Hash Join</span>  (cost=1.02..4016.02 rows=100000 width=197)
106          Hash Cond: (a.bid = b.bid)
107          ->  <span class="strong">Seq Scan on pgbench_accounts a</span>  (cost=0.00..2640.00 rows=100000 width=97)
108          ->  Hash  (cost=1.01..1.01 rows=1 width=100)
109                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
110 (7 rows)
111
112 postgres=# </pre>
113
114 <h3 id="hint-type">ヒントのグループ</h3>
115 <p>pg_hint_planで使えるヒントのグループは、スキャン方式と結合方式、結合順序、GUCパラメータの4通りに分けられます。同じグループのヒントを同じオブジェクトに対して指定した場合は、最後に指定したヒントが適用されます。各グループの具体的なヒントは、<a href="hint_list-ja.html">ヒント一覧</a>を参照してください。</p>
116
117 <h4>スキャン方式</h4>
118 <p>テーブルに対して、どんなスキャンを選択するか指定できるヒントのグループのことです。
119 特定のテーブルに対するスキャン方式を選択したい場合は、そのスキャン方式のヒントと、対象となるオブジェクトの名前を指定してください。
120 特定のテーブルに対するスキャン方式を選択してほしくない場合は、そのスキャン方式のヒントの先頭に No を記述した上で、対象となるオブジェクトの名前を指定してください。</p>
121 <p>以下に示した具体例について説明します。</br>
122 1つ目のSQL文では、aテーブルにIndex Scanを選択させるヒントを用いたため、実行計画作成時にaテーブルに対してIndex Scanを選択しています。</br>
123 2つ目のSQL文では、aテーブルにIndex Scan以外を選択させるヒントを用いたため、実行計画作成時にaテーブルに対してIndex Scan以外のスキャン方式であるSeq Scanを選択しています。</p>
124 <pre>postgres=# /* <span class="strong">IndexScan(a)</span> */
125 postgres-# EXPLAIN SELECT *
126 postgres-#    FROM pgbench_accounts a
127 postgres-#   ORDER BY aid;
128                                                QUERY PLAN
129 ---------------------------------------------------------------------------------------------------------
130  <span class="strong">Index Scan</span> using pgbench_accounts_pkey on pgbench_accounts a  (cost=0.00..4247.26 rows=100000 width=97)
131 (1 row)
132
133 postgres=# /* <span class="strong">NoIndexScan(a)</span> */
134 postgres-# EXPLAIN SELECT *
135 postgres-#    FROM pgbench_accounts a
136 postgres-#   ORDER BY aid;
137                                    QUERY PLAN
138 ---------------------------------------------------------------------------------
139  Sort  (cost=21885.82..22135.82 rows=100000 width=97)
140    Sort Key: aid
141    ->  <span class="strong">Seq Scan</span> on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
142 (3 rows)
143
144 postgres=#
145 </pre>
146 <h4>結合方式</h4>
147 <p>テーブルの結合に対して、どんな結合を選択するか指定できるヒントのグループのことです。
148 特定の結合方式を選択したい場合は、その結合方式のヒントと、対象となる2つ以上のオブジェクトの名前を指定してください。
149 特定の結合方式を選択してほしくない場合は、その結合方式のヒントの先頭に No を記述した上で、対象となるオブジェクトの名前を指定してください。</p>
150 <p>以下に示した具体例について説明します。</br>
151 1つ目のSQL文では、aテーブルとbテーブルの結合にMerge Joinを選択させるヒントを用いたため、実行計画作成時にMerge Joinを選択しています。</br>
152 2つ目のSQL文では、aテーブルとbテーブルの結合にMerge Join以外を選択させるヒントを用いたため、実行計画作成時にMerge Join以外の結合方式であるNested Loopを選択しています。</p>
153 <pre>
154 postgres=# /*
155 postgres*#   <span class="strong">MergeJoin(b a)</span>
156 postgres*#  */
157 postgres-# EXPLAIN SELECT *
158 postgres-#    FROM pgbench_branches b
159 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid;
160                                          QUERY PLAN
161 ---------------------------------------------------------------------------------------------
162  <span class="strong">Merge Join</span>  (cost=21886.84..23636.85 rows=100000 width=197)
163    Merge Cond: (b.bid = a.bid)
164    ->  Sort  (cost=1.02..1.02 rows=1 width=100)
165          Sort Key: b.bid
166          ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
167    ->  Materialize  (cost=21885.82..22385.82 rows=100000 width=97)
168          ->  Sort  (cost=21885.82..22135.82 rows=100000 width=97)
169                Sort Key: a.bid
170                ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
171 (9 rows)
172
173 postgres=# /*
174 postgres*#   <span class="strong">NoMergeJoin(b a)</span>
175 postgres*#  */
176 postgres-# EXPLAIN SELECT *
177 postgres-#    FROM pgbench_branches b
178 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid;
179                                    QUERY PLAN
180 ---------------------------------------------------------------------------------
181  <span class="strong">Nested Loop</span>  (cost=0.00..3891.01 rows=100000 width=197)
182    Join Filter: (b.bid = a.bid)
183    ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
184    ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
185 (4 rows)
186
187 postgres=#</pre>
188 <h3>結合順序</h3>
189 <p>テーブルの結合に対して、どんな順番で結合するか指定できるヒントのグループのことです。
190 結合の順番を指定したい場合は、結合順序のヒント(Leading)と、2つ以上のオブジェクトの名前を結合したい順番で指定してください。</p>
191 <p>以下に示した具体例について説明します。</br>
192 この例では、bテーブルとaテーブルを結合させた後、この結合テーブルとtテーブルを結合させるヒントを用いたため、実行計画作成時にヒントで指定したテーブル順でテーブル結合を選択しています。</p>
193 <pre>postgres=# /*
194 postgres*#  <span class="strong">Leading(b a t)</span>
195 postgres*#  */
196 postgres-# EXPLAIN SELECT *
197 postgres-#    FROM pgbench_branches b
198 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
199 postgres-#    JOIN pgbench_tellers t ON b.bid = t.bid;
200                                                   QUERY PLAN
201 --------------------------------------------------------------------------------------------------------------
202  Hash Join  (cost=1.23..15399.49 rows=1000000 width=297)
203    <span class="strong">Hash Cond: (b.bid = t.bid)</span>
204    ->  Nested Loop  (cost=0.00..3898.27 rows=100000 width=197)
205          <span class="strong">Join Filter: (b.bid = a.bid)</span>
206          ->  Index Scan using pgbench_branches_pkey on pgbench_branches b  (cost=0.00..8.27 rows=1 width=100)
207          ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
208    ->  Hash  (cost=1.10..1.10 rows=10 width=100)
209          ->  Seq Scan on pgbench_tellers t  (cost=0.00..1.10 rows=10 width=100)
210 (8 rows)
211
212 postgres=#</pre>
213 <h3>GUCパラメータ</h3>
214 <p>1クエリ限りでGUCパラメータを設定できるヒントのグループのことです。
215 1クエリ限りでGUCパラメータを設定したい場合は、GUCパラメータを設定するためのヒント(Set)と、設定したいGUCパラメータとそのパラメータの値を指定してください。ただし、指定する値に小文字とアンダースコア(_)以外の文字(大文字、数字、空白スペースなど)を含む場合はダブルクォート(")で囲んでください。</p>
216 <p>以下に示した具体例について説明します。</br>
217 1つ目のSQL文は、GUCパラメータのenable_hashjoinとenable_nestloopをoffに設定するヒントを用いたため、実行計画作成時に各テーブル間の結合でMerge Joinを選択しています。</br>
218 2つ目のSQL文は、GUCパラメータのjoin_collapse_limitを1に設定するヒントを用いたため、実行計画作成時にFROM句で指定したテーブル順でテーブル結合を選択しています。</p>
219 <pre>postgres=# /*
220 postgres*#   Set(enable_hashjoin off)
221 postgres*#   Set(enable_nestloop off)
222 postgres*#  */
223 postgres-# EXPLAIN SELECT *
224 postgres-#    FROM pgbench_branches b
225 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
226 postgres-#    JOIN pgbench_tellers t ON b.bid = t.bid;
227                                          QUERY PLAN
228 ---------------------------------------------------------------------------------------------
229  <span class="strong">Merge Join</span>  (cost=21888.11..37138.29 rows=1000000 width=297)
230    Merge Cond: (b.bid = a.bid)
231    ->  <span class="strong">Merge Join</span>  (cost=2.29..2.44 rows=10 width=200)
232          Merge Cond: (b.bid = t.bid)
233          ->  Sort  (cost=1.02..1.02 rows=1 width=100)
234                Sort Key: b.bid
235                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
236          ->  Sort  (cost=1.27..1.29 rows=10 width=100)
237                Sort Key: t.bid
238                ->  Seq Scan on pgbench_tellers t  (cost=0.00..1.10 rows=10 width=100)
239    ->  Materialize  (cost=21885.82..22385.82 rows=100000 width=97)
240          ->  Sort  (cost=21885.82..22135.82 rows=100000 width=97)
241                Sort Key: a.bid
242                ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
243 (14 rows)
244
245 postgres=# /*
246 postgres*#   Set(join_collapse_limit "1")
247 postgres*#  */
248 postgres-# EXPLAIN SELECT *
249 postgres-#    FROM pgbench_branches b
250 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
251 postgres-#    JOIN pgbench_tellers t ON b.bid = t.bid;
252                                                   QUERY PLAN
253 --------------------------------------------------------------------------------------------------------------
254  Hash Join  (cost=1.23..15399.49 rows=1000000 width=297)
255    Hash Cond: (b.bid = t.bid)
256    ->  Nested Loop  (cost=0.00..3898.27 rows=100000 width=197)
257          Join Filter: (b.bid = a.bid)
258          ->  Index Scan using pgbench_branches_pkey on pgbench_branches b  (cost=0.00..8.27 rows=1 width=100)
259          ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
260    ->  Hash  (cost=1.10..1.10 rows=10 width=100)
261          ->  Seq Scan on pgbench_tellers t  (cost=0.00..1.10 rows=10 width=100)
262 (8 rows)
263
264 postgres=#</pre>
265
266 <h3 id="hint-GUC">pg_hint_planのGUCパラメータ</h3>
267 <p>pg_hint_planツールに関するGUCパラメータを以下に記述します。</p>
268 <table>
269 <thead>
270 <tr>
271 <tr><th>GUCパラメータ</th><th>説明</th><th>デフォルト値</th></tr>
272 </tr></thead>
273 <tbody>
274 <tr><td>pg_hint_plan.enable</td>
275   <td>on のとき、pg_hint_planの機能を有効にします。</td><td>on</td></tr>
276 <tr><td>pg_hint_plan.debug_print</td>
277   <td>on のとき、プランナが実行計画を生成するときに用いたヒントを表示します。</td><td>off</td></tr>
278 <tr><td>pg_hint_plan.parse_message</td>
279   <td>指定したヒントに対して、どのメッセージ階層を表示するかを指定します。有効な値は、debug5、debug4、debug3、debug2、debug1、log、info、notice、warningまたはerrorです。</td><td>info</td></tr>
280 </tbody>
281 </table>
282
283 <h2 id="restrictions">使用上の注意と制約</h2>
284 <p>pg_hint_planを使用する際には、以下の注意と制約があります。</p>
285 <dl>
286 <dt>ヒントの記述位置</dt>
287 <dd>クエリの前に複数のブロックコメントを記述する場合は、最初のブロックコメントにのみヒントを記述してください。二番目以降のブロックコメントは、ヒントと見なされず無視されます。以下の例では、HashJoin(a b)とSeqScan(a)がヒントと見なされ、IndexScan(a)とMergeJoin(a b)は無視されています。</p>
288 <pre>
289 postgres=# /*
290 postgres*#    <span class="strong">HashJoin(a b)</span>
291 postgres*#    <span class="strong">SeqScan(a)</span>
292 postgres*#  */
293 postgres-# /* IndexScan(a) */
294 postgres-# EXPLAIN SELECT /* MergeJoin(a b) */ *
295 postgres-#    FROM pgbench_branches b
296 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
297 postgres-#   ORDER BY a.aid;
298                                       QUERY PLAN
299 ---------------------------------------------------------------------------------------
300  Sort  (cost=31465.84..31715.84 rows=100000 width=197)
301    Sort Key: a.aid
302    ->  <span class="strong">Hash Join</span>  (cost=1.02..4016.02 rows=100000 width=197)
303          Hash Cond: (a.bid = b.bid)
304          ->  <span class="strong">Seq Scan on pgbench_accounts a</span>  (cost=0.00..2640.00 rows=100000 width=97)
305          ->  Hash  (cost=1.01..1.01 rows=1 width=100)
306                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
307 (7 rows)
308
309 postgres=# </pre>
310 </dd>
311 <dt>オブジェクト名の指定方法</dt>
312 <dd><p>ヒント対象のオブジェクト名に小文字とアンダースコア(_)以外の文字(大文字、数字、空白スペースなど)を含む場合は、ダブルクォート(")で囲んでください。</p><p>また、クエリ中に同一名称のテーブルが複数回出現する場合(スキーマ違いや同一テーブルの複数回使用など)は、テーブルに別名をつけてそれぞれのテーブルを区別してください。以下の例の1つ目のSQL文では、MergeJoin(t1 t1)をヒントに指定したとき、ヒント対象のオブジェクトが特定できずにエラーになっています。2つ目のSQL文では、各テーブルにptやstという別名をつけているため、実行計画作成時にヒントで指定した通りにMerge Joinを選択しています。
313 </p>
314 <pre>
315 postgres=# /* <span class="strong">MergeJoin(t1 t1)</span>*/
316 postgres-# EXPLAIN SELECT * FROM s1.t1
317 postgres-# JOIN public.t1 ON (s1.t1.id=public.t1.id);
318 INFO:  hint syntax error at or near "t1 t1)"
319 <span class="strong">DETAIL:  relation name "t1" is ambiguous</span>
320 INFO:  hint syntax error at or near "t1 t1)"
321 <span class="strong">DETAIL:  relation name "t1" is ambiguous</span>
322                              QUERY PLAN
323 --------------------------------------------------------------------
324  Hash Join  (cost=270.00..323.05 rows=1230 width=44)
325    Hash Cond: (s1.t1.id = public.t1.id)
326    ->  Seq Scan on t1  (cost=0.00..22.30 rows=1230 width=36)
327    ->  Hash  (cost=145.00..145.00 rows=10000 width=8)
328          ->  Seq Scan on t1  (cost=0.00..145.00 rows=10000 width=8)
329 (5 rows)
330
331 postgres=# /* <span class="strong">MergeJoin(pt st)</span> */
332 postgres-# EXPLAIN SELECT * FROM s1.t1 st
333 postgres-# JOIN public.t1 pt ON (st.id=pt.id);
334                                     QUERY PLAN
335 ----------------------------------------------------------------------------------
336  <span class="strong">Merge Join</span>  (cost=0.00..421.33 rows=1230 width=44)
337    Merge Cond: (st.id = pt.id)
338    ->  Index Scan using t1_id_idx on t1 st  (cost=0.00..62.70 rows=1230 width=36)
339    ->  Index Scan using t1_pkey on t1 pt  (cost=0.00..318.25 rows=10000 width=8)(4 rows)
340
341 postgres=#</pre>
342 </p>
343 </dd>
344 <dt>ヒントの記述誤り</dt>
345 <dd>pg_hint_planでは、ヒントの記述に誤りがあった場合は、誤った記述に関する情報を出力しますがエラー終了しません。誤った記述より前のヒントのみ有効となり、誤った記述以降のヒントを無視してクエリを実行します。</dd>
346 <dt>指定するヒントの種類の重複</dt>
347 <dd>同じオブジェクトに対して同じグループのヒントを重複して指定した場合は、最後に指定したヒントを使用します。</dd>
348 <dt>ビューに対する制限</dt>
349 <dd>ビューを複数用いるときに、各ビュー内のテーブルの別名が重複した場合は、ヒントの対象を区別できません。区別する場合は、各ビュー内のテーブルの別名を重複させないでください。</dd>
350 </dl>
351
352 <h2 id="known-issues">既知の問題</h2>
353 <p>pg_hint_planに関する既知の問題について説明します。</p>
354 <dl>
355 <dt>副問い合わせを含むSELECT文</dt>
356 <dd id="view_limit">pg_hint_planの使用中に副問い合わせを含むSELECT文を実行すると、サーバ側で異常終了する場合があります。よって、pg_hint_planを試用しているときは、副問い合わせを含むSELECT文を実行しないでください。</dd>
357 </dl>
358
359 <h2 id="seealso">関連項目</h2>
360 <h3 id="postgresql_document">PostgreSQLドキュメント</h3>
361 <a href="http://www.postgresql.org/docs/9.1/static/sql-explain.html">EXPLAIN</a>
362 <hr>
363
364 <div class="navigation">
365   <a href="pg_hint_plan-ja.html">pg_hint_plan</a>
366 </div>
367
368 <p class="footer">Copyright (c) 2012, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
369
370 <!--
371 <script type="text/javascript">
372 var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
373 document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
374 </script><script src="pg_statsinfo-ja_files/ga.js" type="text/javascript"></script>
375 <script type="text/javascript">
376 try{
377 var pageTracker = _gat._getTracker("UA-10244036-6");
378 pageTracker._trackPageview();
379 } catch(err) {}
380 </script>
381 -->
382 </body>
383 </html>