OSDN Git Service

0c0fcfebe6a543d8c2baaceb8aaf5b48d9587174
[pghintplan/pg_hint_plan.git] / doc / pg_hint_plan.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html lang="en_US">
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 <!--
11 <style type="text/css">
12 h2 { border-style:solid none none none; margin-top: 2em; }
13 h3 { margin-top: 2em; }
14 dt { margin-top: 0.5em; margin-bottom: 0.3em;}
15 pre { margin: 0 2em 0 2em; padding:0.3em; border-style: solid; border-width:0.1em; border-color: #97A69F; background-color: #DEFFEF; }
16 </style>
17 -->
18 </head>
19
20 <body>
21 <h1 id="pg_hint_plan">pg_hint_plan 1.1</h1>
22 <div class="navigation">
23   <a href="pg_hint_plan-ja.html">pg_hint_plan</a>
24 </div>
25 <hr>
26
27 <div class="index">
28 <ol>
29 <li><a href="#name">Name</a></li>
30 <li><a href="#synopsis">Synopsis</a></li>
31 <li><a href="#description">Description</a>
32 <li><a href="#install">Installation</a></li>
33 <li><a href="#uninstall">Uninstallation</a></li>
34 <li><a href="#examples">Hint descriptions</a></li>
35 <li><a href="#hint_syntax">Hint syntax</a></li>
36 <li><a href="#restrictions">Restrictions</a></li>
37 <li><a href="#technics">Technics to hint on disired targets</a></li>
38 <li><a href="#errors">Errors of hints</a></li>
39 <li><a href="#func_limits">Functional limitations</a></li>
40 <li><a href="#requirement">Requirements</a></li>
41 <li><a href="#seealso">See Also</a></li>
42 <li><a href="hint_list.html">Appendix A. Hints list</a></li>
43 </div>
44
45 <h2 id="name">Name</h2>
46 <p>pg_hint_plan -- controls execution plan with hinting phrases in comment of special form.</p>
47
48 <h2 id="synopsis">Synopsis</h2>
49 <p>PostgreSQL uses cost based optimizer, which utilizes data statistics, not static rules. The planner (optimizer) esitimates costs of each possible execution plans for a SQL statement then the execution plan with the lowest cost finally be executed.  The planner does its best to select the best best execution plan, but not perfect, since it doesn't count some properties of the data, for example, correlation between columns.</p>
50 <p>pg_hint_plan makes it possible to tweak execution plans using so-called "hints", which are simple descriptions in the SQL comment of special form.</p>
51
52 <h2 id="description">Description</h2>
53
54 <h3 id="hint-rule">Basic Usage</h3>
55 <p>pg_hint_plan reads hinting phrases in a comment of special form given with the target SQL statement. The special form is beginning by the character sequence "/*+" and ends with "*/". Hint phrases are consists of hint name and following parameters enclosed by parentheses and delimited by spaces. Each hinting phrases can be delimited by new lines for readability.</p>
56
57 <p>In the example below , hash join is selected as the joning method and scanning pgbench_accounts by sequential scan method.</p>
58 <pre>
59 postgres=# /*+
60 postgres*#    <span class="strong">HashJoin(a b)</span>
61 postgres*#    <span class="strong">SeqScan(a)</span>
62 postgres*#  */
63 postgres-# EXPLAIN SELECT *
64 postgres-#    FROM pgbench_branches b
65 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
66 postgres-#   ORDER BY a.aid;
67                                       QUERY PLAN
68 ---------------------------------------------------------------------------------------
69  Sort  (cost=31465.84..31715.84 rows=100000 width=197)
70    Sort Key: a.aid
71    ->  <span class="strong">Hash Join</span>  (cost=1.02..4016.02 rows=100000 width=197)
72          Hash Cond: (a.bid = b.bid)
73          ->  <span class="strong">Seq Scan on pgbench_accounts a</span>  (cost=0.00..2640.00 rows=100000 width=97)
74          ->  Hash  (cost=1.01..1.01 rows=1 width=100)
75                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
76 (7 rows)
77
78 postgres=# </pre>
79
80 <h3 id="hint-group">The types of hints</h3>
81 <p>Hinting phrases are classified into four types based on what kind of object they can affect. Scaning methods, join methods, joining order, row number correction and GUC setting. You will see the lists of hint phrases of each type in <a href="hint_list.html">Hint list</a>.</p>
82
83 <h4>Hints for scan methods </h4>
84 <p>Scan method hints enforce the scanning method on the table specified as parameter. pg_hint_plan recognizes the target table by alias names if any. They are 'SeqScan' , 'IndexScan' and so on.</p>
85 <p>Scan hints are effective on ordinary tables, inheritance tables, UNLOGGED tables, temporary tables and  system catalogs. It cannot be applicable on external(foreign) tables, table functions, VALUES command results, CTEs, Views and Sub-enquiries.</p>
86
87
88 <h4>Hints for join methods</h4>
89 <p>Join method hints enforces the join methods of the joins consists of tables specified as parameters. </p>
90 <p>Ordinary tables, inheritance tables, UNLOGGED tables, temporary tables, external (foreign) tables, system catalogs, table functions, VALUES command results and CTEs are allowed to be in the parameter list. But views and sub query are not.</p>
91
92 <h4>Hint for joining order</h4>
93 <p> Joining in specific order can be enforced using the "Leading" hint. The objects are joined in the order of the objects in the parameter list.</p>
94
95 <h4>Hint for row number correction</h4>
96 <p>From the restriction of the planner's capability, it misestimates the number of results on some conditions. This type of hint corrects it. </p>
97
98 <h4>GUC parameters temporarily setting</h4>
99 <p>'Set' hint changes GUC parameters just while planning. GUC parameter shown in <a href="http://www.postgresql.org/docs/current/static/runtime-config-query.html">Query Planning</a> can have the expected effects on planning unless any other hint conflicts with the planner method configuration parameters. The last one among hints on the same GUC parameter makes effect. <a href="#hint-GUC">GUC parameters for pg_hint_plan</a> are also settable by  this hint but it won't work as your expectation. See <a href="#restrictions">Restrictions</a> for details.</p>
100
101 <h3 id="hint-GUC">GUC parameters for pg_hint_plan</h3>
102 <p>GUC parameters below affect the behavior of pg_hint_planpg_hint_plan.</p>
103 <table>
104 <thead>
105 <tr>
106 <tr><th>Parameter name</th><th>discription</th><th>Default</th></tr>
107 </tr></thead>
108 <tbody>
109 <tr><td>pg_hint_plan.enable_hint</td>
110   <td>Enbles or disables the function of pg_hint_plan.</td><td>on</td></tr>
111 <tr><td>pg_hint_plan.enable_hint_table</td>
112   <td>Enbles or disables table-based hinting.</td><td>on</td></tr>
113 <tr><td>pg_hint_plan.debug_print</td>
114   <td>Enables and select the verbosity of the debug output of pg_hint_plan. Valid options are off, on, detailed and verbose.</td><td>off</td></tr>
115 <tr><td>pg_hint_plan.message_level</td>
116   <td>Specifies the message level of debug prints. error, warning, notice, info, log, debug<n> are valid and fatal and panic are inhibited.</td><td>info</td></tr>
117 </tbody>
118 </table>
119 <h2 id="install">Installation</h2>
120 This section describes the installation steps.
121 <h3 id="build">building binary module</h3>
122 <p>Simplly run "make" in the top of the source tree, then "make install" as appropriate user. The PATH environment variable should be set properly for the target PostgreSQL for this process. </p>
123 <pre>
124 $ tar xzvf pg_hint_plan-1.x.x.tar.gz
125 $ cd pg_hint_plan-1.x.x
126 $ make
127 $ su
128 # make install
129 </pre>
130
131 <h3 id="hint-load">Loding pg_hint_plan</h3>
132 <p>Basically pg_hint_plan does not requires CREATE EXTENSION. Simplly loading it by LOAD command will activate it and of course you can load it globally by setting shared_preload_libraries in postgresql.conf. Or you might be interested in ALTER USER SET/ALTER DATABASE SET for automatic loading for specific sessions. 
133 <pre>
134 postgres=# LOAD 'pg_hint_plan';
135 LOAD
136 postgres=# </pre></p>
137
138 <p>Do CREATE EXTENSION and SET pg_hint_plan.enable_hint_tables TO on if you are planning to hint tables.</p>
139
140
141 <h2 id="uninstall">Unistallation</h2>
142 <p>"make uninstall" in the top directory of source tree will uninstall the installed files if you installed from the source tree and it is left available. </p>
143
144 <pre>
145 $ cd pg_hint_plan-1.x.x
146 $ su
147 # make uninstall
148 </pre>
149
150
151 <h2 id="examples">Hint descriptions</h2>
152 This section explains how to spell each type of hints.
153 <h3>Scan method hints</h3>
154 <p>Scan hints have basically has one parameter to specify the target object. This additional parameter for scans using indexes is preferable index name. The target object should be specified by its alias name if any. In the following example, table1 is scanned by sequential scan and  table2 is scanned using the primary key index.
155 <pre>
156 postgres=# /*+
157 postgres*#     SeqScan(t1)
158 postgres*#     IndexScan(t2 t2_pkey)
159 postgres*#  */
160 postgres-# SELECT * FROM table1 t1 JOIN table table2 t2 ON (t1.key = t2.key);
161 </pre>
162 </p>
163
164 <h3>Join method hints</h3>
165 <p>Join hints have two or more objects which compose the join as parameters. If three objects are specified, the hint will be applied when joining any one of them after joining other two objects. In the following example, table1 and table2 are joined fisrt using nested loop and the result is joined against table3 using merge join.</p>
166  
167 <pre>
168 postgres=# /*+
169 postgres*#     NestLoop(t1 t2)
170 postgres*#     MergeJoin(t1 t2 t3)
171 postgres*#     Leading(t1 t2 t3)
172 postgres*#  */
173 postgres-# SELECT * FROM table1 t1
174 postgres-#     JOIN table table2 t2 ON (t1.key = t2.key)
175 postgres-#     JOIN table table3 t3 ON (t2.key = t3.key);
176 </pre>
177
178 <h3>Joining order hints</h3>
179 <p>Although there might be the case that table2 and 3 are joined first and table1 after that and the NestLoop hint won't be in effect after all. "Leading" hint enforces the joining order for the cases. The Leading hint in the above example enforces the joining order to table1, 2, 3 then both join method hints will be effective.</p>
180 <p>
181 The above form of Leading hint enforces joining order but joining direction (inner/outer or driven/driving assignment) is left to the planner. If you want to also enforce joining directions, the second form of this hint will help.
182 </p>
183 <pre>
184 postgres=# /*+ Leading((t1 (t2 t3))) */ SELECT...
185 </pre>
186 <p>
187 Every pair of parentheses enclose two elements which are an object or nested parentheses. The first element in a pair of parentheses is the driver or outer table and the second is the driven or inner.
188 </p>
189
190 <h3>Row number correction hints</h3>
191 <p>
192 Planner misestimates the number of the records for joins on some condition. This hint can corrects the number by several methods, which are absolute value, addition/subtraction and multiplication. The parameters are the list of objects compose the targetted join then operation. The following example shows notations to correct the number of the join on a and b by the four correction methods.
193 </p>
194 <pre>
195 postgres=# /*+ Rows(a b #10) */ SELECT... ; Sets rows of join result to 10
196 postgres=# /*+ Rows(a b +10) */ SELECT... ; Increments row number by 10
197 postgres=# /*+ Rows(a b -10) */ SELECT... ; Subtracts 10 from the row number.
198 postgres=# /*+ Rows(a b *10) */ SELECT... ; Makes the number 10 times larger.
199 </pre>
200
201 <h3>GUC temporarily setting</h3>
202 <p>
203 "Set" hint sets GUC parameter values during the target statement is under plannning. In the following example, planning for the query is done with random_page_cost is 2.0. 
204 <pre>
205 postgres=# /*+
206 postgres*#     Set(random_page_cost 2.0)
207 postgres*#  */
208 postgres-# SELECT * FROM table1 t1 WHERE key = 'value';
209 ...
210 </pre>
211 </p>
212
213 <h2 id="hint_syntax">Hint syntax</h2>
214 <dl>
215 <dt>Hint comment location</dt>
216 <dd>pg_hint_plan reads hints from only the first block comment, and any characters except alphabets, digits, spaces, underscores, commas and parentheses are not allowed before the comment. In the following example HashJoin(a b) and SeqScan(a) are recognized as Hint and IndexScan(a) and MergeJoin(a b) is not.
217 <pre>
218 postgres=# /*+
219 postgres*#    <span class="strong">HashJoin(a b)</span>
220 postgres*#    <span class="strong">SeqScan(a)</span>
221 postgres*#  */
222 postgres-# /*+ IndexScan(a) */
223 postgres-# EXPLAIN SELECT /*+ MergeJoin(a b) */ *
224 postgres-#    FROM pgbench_branches b
225 postgres-#    JOIN pgbench_accounts a ON b.bid = a.bid
226 postgres-#   ORDER BY a.aid;
227                                       QUERY PLAN
228 ---------------------------------------------------------------------------------------
229  Sort  (cost=31465.84..31715.84 rows=100000 width=197)
230    Sort Key: a.aid
231    ->  <span class="strong">Hash Join</span>  (cost=1.02..4016.02 rows=100000 width=197)
232          Hash Cond: (a.bid = b.bid)
233          ->  <span class="strong">Seq Scan on pgbench_accounts a</span>  (cost=0.00..2640.00 rows=100000 width=97)
234          ->  Hash  (cost=1.01..1.01 rows=1 width=100)
235                ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
236 (7 rows)
237
238 postgres=# </pre>
239 </dd>
240
241 <dt>Using with PL/pgSQL</dt>
242 <dd>pg_hint_plan works for queries in PL/pgSQL scripts with some restrictions.
243 <ul>
244  <li>Hints affect only on the following kind of queires.
245  <ul>
246   <li>Queries that returns one row. (SELECT, INSERT, UPDATE and DELETE)</li>
247   <li>Queries that returns multiple rows. (RETURN QUERY)</li>
248   <li>Dynamic SQL statements. (EXECUTE)</li>
249   <li>Cursor open. (OPEN)</li>
250   <li>Loop over result of a query (FOR)</li>
251  </ul>
252
253  <li>A hint comment have to be placed after the first word in a query
254      as the following since preceding comments are not sent as a part
255      of the query.</li>
256 </ul>
257 <pre>
258 postgres=# CREATE FUNCTION hints_func(integer) RETURNS integer AS $$
259 postgres$# DECLARE
260 postgres$#     id  integer;
261 postgres$#     cnt integer;
262 postgres$# BEGIN
263 postgres$#     SELECT <b><u>/*+ NoIndexScan(a) */</u></b> aid
264 postgres$#         INTO id FROM pgbench_accounts a WHERE aid = $1;
265 postgres$#     SELECT <b><u>/*+ SeqScan(a) */</u></b> count(*)
266 postgres$#         INTO cnt FROM pgbench_accounts a;
267 postgres$#     RETURN id + cnt;
268 postgres$# END;
269 postgres$# $$ LANGUAGE plpgsql;
270 </pre>
271 </dd>
272
273 <dt>Letter case in a hinted object</dt>
274 <dd>Unlike the way PostgreSQL handles object names, pg_hint_plan compares bare object names in hints against the database internal object names in case sensitive way. Therefore an object name TBL in a hint matches only "TBL" in database and does not match any unquoted names like TBL, tbl or Tbl.
275 </dd>
276
277 <dt>Escaping special chacaters in object names</dt>
278 <dd>The objects as the hint parameter should be enclosed by double quotes if they includes parentheses, double quotes and white spaces. The escaping rule is the same as PostgreSQL.
279 </dd>
280 <dt>Distinction among table occurrences with the same name </dt>
281 <dd>Target name duplication caused by multiple occurrences of the same object or objects with the same name in different name spaces can be avoided by giving alias names for each occurrence in the target query and using them in hint phases.
282 The example below, the first SQL statement results in error from using a table name appeared twice in the target query, while the second example works since each occurrence of table t1 is given a distinct alias name and specified in the HashJoin hint using it.
283 <pre>
284 postgres=# /*+ <span class="strong">HashJoin(t1 t1)</span>*/
285 postgres-# EXPLAIN SELECT * FROM s1.t1
286 postgres-# JOIN public.t1 ON (s1.t1.id=public.t1.id);
287 INFO:  hint syntax error at or near "HashJoin(t1 t1)"
288 <span class="strong">DETAIL:  Relation name "t1" is ambiguous.</span>
289                             QUERY PLAN
290 ------------------------------------------------------------------
291  Merge Join  (cost=337.49..781.49 rows=28800 width=8)
292    Merge Cond: (s1.t1.id = public.t1.id)
293    ->  Sort  (cost=168.75..174.75 rows=2400 width=4)
294          Sort Key: s1.t1.id
295          ->  Seq Scan on t1  (cost=0.00..34.00 rows=2400 width=4)
296    ->  Sort  (cost=168.75..174.75 rows=2400 width=4)
297          Sort Key: public.t1.id
298          ->  Seq Scan on t1  (cost=0.00..34.00 rows=2400 width=4)
299 (8 行)
300
301 postgres=# /*+ <span class="strong">HashJoin(pt st)</span> */
302 postgres-# EXPLAIN SELECT * FROM s1.t1 st
303 postgres-# JOIN public.t1 pt ON (st.id=pt.id);
304                              QUERY PLAN
305 ---------------------------------------------------------------------
306  <span class="strong">Hash Join</span>  (cost=64.00..1112.00 rows=28800 width=8)
307    Hash Cond: (st.id = pt.id)
308    ->  Seq Scan on t1 st  (cost=0.00..34.00 rows=2400 width=4)
309    ->  Hash  (cost=34.00..34.00 rows=2400 width=4)
310          ->  Seq Scan on t1 pt  (cost=0.00..34.00 rows=2400 width=4)
311 (5 行)
312 </dd>
313
314 <dt>Underlying tables of views or rules</dt>
315 <dd>Hints are not applicable on views itself, but they can affect the
316 queries within if the object names match the object names in the
317 expanded query on the view. Assigning aliases to the tables in a view
318 enables them to be manipulated from outside the view.
319 <pre>
320 <b>postgres=#</b> CREATE VIEW v1 AS SELECT * FROM <b><u>t2</u></b>;
321 <b>postgres=#</b> EXPLAIN <b>/*+ HashJoin(t1 v1) */</b>
322           SELECT * FROM t1 JOIN v1 ON (c1.a = v1.a);
323                             QUERY PLAN                            
324 ------------------------------------------------------------------
325  Hash Join  (cost=3.27..18181.67 rows=101 width=8)
326    Hash Cond: (t1.a = t2.a)
327    ->  Seq Scan on t1  (cost=0.00..14427.01 rows=1000101 width=4)
328    ->  Hash  (cost=2.01..2.01 rows=101 width=4)
329          ->  Seq Scan on t2  (cost=0.00..2.01 rows=101 width=4)
330 </pre>
331 </dd>
332
333 <dt>Inheritance tables</dt>
334 <dd>Hints can point only the parent of an inheritance tables and the
335 hint affect all the inheritance. Hints simultaneously point directly
336 to children are not in effect.
337 </dd>
338
339 <dt>Hinting on multistatements</dt>
340 <dd>One multistatement can have exactly one hint comment and the hints affects all of the individual statement in the multistatement. Notice that the seemingly multistatement on the interactive interface of psql is internally a sequence of single statements so hints affects only on the statement just following.</dd>
341
342 <dt>VALUES expressions</dt>
343 <dd>VALUES expressions in FROM clause are named as *VALUES* internally
344 so it is hintable if it is the only VALUES in a query. Two or more
345 VALUES expressions in a query seems distinguishable looking its
346 explain result. But in reality it is mere a cosmetic and they are not
347 distinguisable.
348 <pre>
349 postgres=# CREATE VIEW view1 AS SELECT * FROM table1 <span class="strong">t1</span>;
350 CREATE TABLE
351 postgres=# /*+ SeqScan(<span class="strong">t1</span>) */
352 postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t1</span> JOIN view1 t2 ON (t1.key = t2.key) WHERE t2.key = 1;
353                            QUERY PLAN
354 -----------------------------------------------------------------
355  Nested Loop  (cost=0.00..358.01 rows=1 width=16)
356    ->  Seq Scan on table1 <span class="strong">t1</span>  (cost=0.00..179.00 rows=1 width=8)
357          Filter: (key = 1)
358    ->  Seq Scan on table1 <span class="strong">t1</span>  (cost=0.00..179.00 rows=1 width=8)
359          Filter: (key = 1)
360 (5 rows)
361
362 postgres=# /*+ SeqScan(<span class="strong">t3</span>) */
363 postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t3</span> JOIN view1 t2 ON (t1.key = t2.key) WHERE t2.key = 1;
364                                    QUERY PLAN
365 --------------------------------------------------------------------------------
366  Nested Loop  (cost=0.00..187.29 rows=1 width=16)
367    ->  Seq Scan on table1 <span class="strong">t3</span>  (cost=0.00..179.00 rows=1 width=8)
368          Filter: (key = 1)
369    ->  Index Scan using foo_pkey on table1 t1  (cost=0.00..8.28 rows=1 width=8)
370          Index Cond: (key = 1)
371 (5 rows)
372
373 </pre>
374 </dd>
375 <dt>Hinting on the hinheritance children</dt>
376 <dd>Hints targeted on inheritance parents automatically affect on all their own children. Child tables cannot have their own hint specified. </dd>
377
378 <dt>Scope of hints on multistatement</dt>
379 <dd>One multistatement description can have exactly one hint comment and the hints affects all of the individual statement in the multistatement. Notice that the seemingly multistatement on the interactive interface of psql is internally a sequence of single statements so hints affects only on the statement just following. Conversely, every single statement have their own hint comments affect on them.</dd>
380
381 <dt>Subqueries in some contexts</dt>
382 <dd>Subqueries in the following context also can be hinted.
383 <pre>
384 IN (SELECT ... {LIMIT | OFFSET ...} ...)
385 = ANY (SELECT ... {LIMIT | OFFSET ...} ...)
386 = SOME (SELECT ... {LIMIT | OFFSET ...} ...)
387 </pre>
388 <p>For these syntaxes, planner internally assigns the name of "ANY_subquery" to the subquery when planning joins including it, so join hints are applicable on such joins using the implicit name.</p>
389 <pre>
390 postgres=# /*+HashJoin(a1 ANY_subquery)*/
391 postgres=# EXPLAIN SELECT *
392 postgres=#    FROM pgbench_accounts a1
393 postgres=#   WHERE aid IN (SELECT bid FROM pgbench_accounts a2 LIMIT 10);
394                                          QUERY PLAN
395
396 ---------------------------------------------------------------------------------------------
397  Hash Semi Join  (cost=0.49..2903.00 rows=1 width=97)
398    Hash Cond: (a1.aid = a2.bid)
399    ->  Seq Scan on pgbench_accounts a1  (cost=0.00..2640.00 rows=100000 width=97)
400    ->  Hash  (cost=0.36..0.36 rows=10 width=4)
401          ->  Limit  (cost=0.00..0.26 rows=10 width=4)
402                ->  Seq Scan on pgbench_accounts a2  (cost=0.00..2640.00 rows=100000 width=4)
403 (6 rows)
404 </pre>
405 </dd>
406
407 <dt>Using IndexOnlyScan hint</dt>
408 <dd>You shoud explicitly specify an index that can perform index only scan if you put IndexOnlyScan hint on a table that have other indexes that cannot perform index only scan. Or pg_hint_plan may select them. </dd>
409
410 <dt>Using NoIndexScan hint</dt>
411 <dd>NoIndexScan hint involes NoIndexOnlyScan.</dd>
412 </dl>
413
414 <h2 id="errors">Errors of hints</h2>
415 <dl>pg_hint_plan stops parsing on any error and uses hints already parsed on the most cases. Followings are the typical errors.
416 <dt>Syntax errors </dt>
417 <dd>Any syntactical errors or wrong hint names are reported as an syntax error. These errors are reported in the server log with the message level which specified by pg_hint_plan.message_level if pg_hint_plan.debug_print is on and aboves.</dd>
418 <dt>Object misspecifications</dt>
419 <dd>Object misspecifications results silent ingorance of the hints. This kind of error is reported as "not used hints" in the server log by the same condtion to syntax errors.</dd>
420
421 <dt>Redundant or conflicting hints</dt>
422 <dd>The last hint will be active when redundant hints or hints conflicting with each other. This kind of error is reported as "duplication hints" in the server log by the same condition to syntax errors.</dd>
423
424 <dt>Nested comments</dt>
425 <dd>Hint comment cannot include another block comment within. If pg_hint_plan finds it, differently from other erros, it stops parsing and abandans all hints already parsed. This kind of error is reported in the same manner as other errors. </dd>
426 </dl>
427
428 <h2 id="func_limits">Functional limitations</h2>
429 <dl>
430 <dt>Influences of some planner GUC parameters</dt>
431 <dd>The planner does not try to consider joining order for FROM clause entries more than from_collapse_limit. pg_hint_plan cannot affect joining order as expected for the case.</dd>
432
433 <dt>Hints trying to enforce unexecutable plans </dt>
434 <dd>pg_hint_plan doesn't enforce plans that cannot be executed.</dd>
435 <ul>
436 <li>FULL OUTER JOIN to use nested loop</li>
437 <li>To use indexes that does not have columns used in quals</li>
438 <li>To do TID scans for queries without ctid conditions</li>
439 </ul>
440 </dd>
441
442 <dt>Queries in ECPG</dt>
443 <dd>ECPG removes comments in queries written as embedded SQLs so hints cannot be passed form those queries. The only exception is that EXECUTE command passes given string unmodifed. Please consider using hint tables in the case.</dd>
444 </dl>
445
446 <h2 id="requirement">Requirements</h2>
447 <dl>
448 <dt>PostgreSQL versions tested</dt>
449   <dd>Version 9.4-11</dd>
450 <dt>OS versions tested</dt>
451   <dd>RHEL 7.5</dd>
452 </dl>
453
454 <h2 id="seealso">See also</h2>
455 <h3 id="postgresql_document">PostgreSQL documents</h3>
456 <a href="http://www.postgresql.org/docs/current/static/sql-explain.html">EXPLAIN</a>
457 <a href="http://www.postgresql.org/docs/current/static/sql-set.html">SET</a>
458 <a href="http://www.postgresql.org/docs/current/static/runtime-config.html">Server Config</a>
459 <hr>
460
461 <div class="navigation">
462   <a href="pg_hint_plan.html">pg_hint_plan</a>
463 </div>
464
465 <p class="footer">Copyright (c) 2012-2019, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
466 </body>
467 </html>