postgres=# </pre>
<h3 id="hint-rule">ヒントの記述方法</h3>
-<p>ヒントはクエリの前のブロックコメント内に、スペース、タブまたは改行のいずれかで区切って記述してください。ヒントの対象は、カッコ内にオブジェクト名または別名(エイリアス)で指定してください。</p>
+<p>ã\83\92ã\83³ã\83\88ã\81¯ã\82¯ã\82¨ã\83ªã\81®å\89\8dã\81®ã\83\96ã\83ã\83\83ã\82¯ã\82³ã\83¡ã\83³ã\83\88å\86\85ã\81«ã\80\81ã\82¹ã\83\9aã\83¼ã\82¹ã\80\81ã\82¿ã\83\96ã\80\81ã\81¾ã\81\9fã\81¯æ\94¹è¡\8cã\81®ã\81\84ã\81\9aã\82\8cã\81\8bã\81§å\8cºå\88\87ã\81£ã\81¦è¨\98è¿°ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82ã\83\92ã\83³ã\83\88ã\81®å¯¾è±¡ã\81¯ã\80\81ã\82«ã\83\83ã\82³å\86\85ã\81«ã\82ªã\83\96ã\82¸ã\82§ã\82¯ã\83\88å\90\8dã\81¾ã\81\9fã\81¯å\88¥å\90\8d(ã\82¨ã\82¤ã\83ªã\82¢ã\82¹)ã\81§æ\8c\87å®\9aã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84ã\80\82</p>
<p>以下の例では、HashJoinとSeqScanヒントにより、pgbench_accountsテーブルに対するSeq Scanの結果をHash Joinする実行計画が選択されています。</p>
<pre>
postgres=# </pre>
<h3 id="hint-group">ヒントのグループ</h3>
-<p>pg_hint_planã\81§ä½¿ã\81\88ã\82\8bã\83\92ã\83³ã\83\88ã\81®ã\82°ã\83«ã\83¼ã\83\97ã\81¯ã\80\81ã\82¹ã\82ã\83£ã\83³æ\96¹å¼\8fã\81¨çµ\90å\90\88æ\96¹å¼\8fã\80\81çµ\90å\90\88é \86åº\8fã\80\81GUCã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81®4é\80\9aã\82\8aに分けられます。同じグループのヒントを同じオブジェクトに対して指定した場合は、最後に指定したヒントが適用されます。各グループの具体的なヒントは、<a href="hint_list-ja.html">ヒント一覧</a>を参照してください。</p>
+<p>pg_hint_planã\81§ä½¿ã\81\88ã\82\8bã\83\92ã\83³ã\83\88ã\81¯ã\80\81ã\82¹ã\82ã\83£ã\83³æ\96¹å¼\8fã\81¨çµ\90å\90\88æ\96¹å¼\8fã\80\81çµ\90å\90\88é \86åº\8fã\80\81GUCã\83\91ã\83©ã\83¡ã\83¼ã\82¿ã\81®4ã\82°ã\83«ã\83¼ã\83\97に分けられます。同じグループのヒントを同じオブジェクトに対して指定した場合は、最後に指定したヒントが適用されます。各グループの具体的なヒントは、<a href="hint_list-ja.html">ヒント一覧</a>を参照してください。</p>
<h4>スキャン方式</h4>
<p>あるテーブルのスキャン方式を選択するかを指定できるヒントのグループで、「SeqScan」や「IndexScan」などが含まれます</p>
</tr></thead>
<tbody>
<tr><td>pg_hint_plan.enable</td>
- <td>on のとき、pg_hint_planの機能を有効にします。</td><td>on</td></tr>
+ <td>pg_hint_planの機能を有効または無効にします。</td><td>on</td></tr>
<tr><td>pg_hint_plan.debug_print</td>
- <td>on のとき、プランナが実行計画を生成するときに用いたヒントを表示します。</td><td>off</td></tr>
-<tr><td>pg_hint_plan.parse_message</td>
- <td>æ\8c\87å®\9aã\81\97ã\81\9fã\83\92ã\83³ã\83\88ã\81«å¯¾ã\81\97ã\81¦ã\80\81ã\81©ã\81®ã\83¡ã\83\83ã\82»ã\83¼ã\82¸é\9a\8e層ã\82\92表示ã\81\99ã\82\8bã\81\8bã\82\92æ\8c\87å®\9aã\81\97ã\81¾ã\81\99ã\80\82æ\9c\89å\8a¹ã\81ªå\80¤ã\81¯ã\80\81debug5ã\80\81debug4ã\80\81debug3ã\80\81debug2ã\80\81debug1ã\80\81logã\80\81infoã\80\81noticeã\80\81warningã\81¾ã\81\9fã\81¯errorã\81§ã\81\99。</td><td>info</td></tr>
+ <td>pg_hint_planのデバッグ出力を有効にします。メッセージはLOGメッセージレベルで出力されますので、デフォルトではサーバログに出力され、クライアントには渡されません。</td><td>off</td></tr>
+<tr><td>pg_hint_plan.parse_messages</td>
+ <td>æ\8c\87å®\9aã\81\97ã\81\9fã\83\92ã\83³ã\83\88ã\82\92解é\87\88ã\81§ã\81\8dã\81ªã\81\8bã\81£ã\81\9få ´å\90\88ã\81«ã\80\81ã\81©ã\81®ã\83¡ã\83\83ã\82»ã\83¼ã\82¸é\9a\8e層ã\81§ã\83ã\82°ã\82\92å\87ºå\8a\9bã\81\99ã\82\8bã\81\8bã\82\92æ\8c\87å®\9aã\81\97ã\81¾ã\81\99ã\80\82æ\9c\89å\8a¹ã\81ªå\80¤ã\81¯ã\80\81debug5ã\80\81debug4ã\80\81debug3ã\80\81debug2ã\80\81debug1ã\80\81logã\80\81infoã\80\81noticeã\80\81warningã\80\81ã\81¾ã\81\9fã\81¯errorã\81§ã\81\99ã\80\82fatalã\81¨panicã\81¯æ\8c\87å®\9aã\81§ã\81\8dã\81¾ã\81\9bã\82\93。</td><td>info</td></tr>
</tbody>
</table>
LOAD 'pg_hint_plan';
SET pg_hint_plan.enable TO on;
SET pg_hint_plan.debug_print TO true;
+SET client_min_messages TO 'LOG';
EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id;
QUERY PLAN
--------------------------------------------
-- 9.2:PREPAREでヒント句を指定しても、実行計画は制御できない
/* NestLoop(t1 t2) */
PREPARE p1 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
EXPLAIN (COSTS false) EXECUTE p1;
-- 9.2:パラメータがない場合は、1回目のEXPLAINで実行計画が決定する
/* NestLoop(t1 t2) */
PREPARE p2 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
/* HashJoin(t1 t2) */
-- 9.2:5回目のEXPLAINまでヒント句を指定しても、6回目以降は本来の実行計画に戻る
/* NestLoop(t1 t2) */
PREPARE p3 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
/* HashJoin(t1 t2) */
-- 9.2:6回目のEXPLAINまでヒント句を指定すると、7回目以降も実行計画が固定される
/* NestLoop(t1 t2) */
PREPARE p4 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
/* HashJoin(t1 t2) */
-- 9.2:6回目のEXPLAINでヒント句を指定すると、7回目以降も実行計画を制御できる
/* NestLoop(t1 t2) */
PREPARE p5 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
EXPLAIN (COSTS false) EXECUTE p5 (10);
-- 9.2:7回目以降のEXPLAINでヒント句を指定しても、以降も実行計画は制御できない
/* NestLoop(t1 t2) */
PREPARE p6 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
EXPLAIN (COSTS false) EXECUTE p6 (10);
-- 9.2:実行計画が固定されたあと、ANALYZEをすると1回目のEXECUTEで実行計画が固定される
/* NestLoop(t1 t2) */
PREPARE p7 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
-INFO: /*
+LOG: /*
NestLoop(t1 t2)
*/
/* HashJoin(t1 t2) */
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
LOAD 'pg_hint_plan';
SET pg_hint_plan.enable TO on;
SET pg_hint_plan.debug_print TO true;
+SET client_min_messages TO 'LOG';
EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id;
QUERY PLAN
-------------------------------------------------
PREPARE p2 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id;
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p2;
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
PREPARE p3 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p3 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p3 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p3 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p3 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p3 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
PREPARE p4 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p4 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p4 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p4 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p4 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p4 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p4 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p5 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p5 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p5 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
PREPARE p7 AS SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > $1;
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
/* HashJoin(t1 t2) */
EXPLAIN (COSTS false) EXECUTE p7 (10);
-INFO: /*
+LOG: /*
HashJoin(t1 t2)
*/
QUERY PLAN
#define HINT_ARRAY_DEFAULT_INITSIZE 8
#define parse_ereport(str, detail) \
- ereport(pg_hint_plan_parse_message, \
+ ereport(pg_hint_plan_parse_messages, \
(errmsg("hint syntax error at or near \"%s\"", (str)), \
errdetail detail))
/* GUC variables */
static bool pg_hint_plan_enable = true;
static bool pg_hint_plan_debug_print = false;
-static int pg_hint_plan_parse_message = INFO;
+static int pg_hint_plan_parse_messages = INFO;
-static const struct config_enum_entry parse_message_level_options[] = {
+static const struct config_enum_entry parse_messages_level_options[] = {
{"debug", DEBUG2, true},
{"debug5", DEBUG5, false},
{"debug4", DEBUG4, false},
NULL,
NULL);
- DefineCustomEnumVariable("pg_hint_plan.parse_message",
+ DefineCustomEnumVariable("pg_hint_plan.parse_messages",
"Messege level of the parse error.",
NULL,
- &pg_hint_plan_parse_message,
+ &pg_hint_plan_parse_messages,
INFO,
- parse_message_level_options,
+ parse_messages_level_options,
PGC_USERSET,
0,
NULL,
if (!hint)
{
- elog(INFO, "no hint");
+ elog(LOG, "no hint");
return;
}
appendStringInfoString(&buf, "*/");
- elog(INFO, "%s", buf.data);
+ elog(LOG, "%s", buf.data);
pfree(buf.data);
}
if (result > 0)
result = set_config_option(hint->name, hint->value, context,
PGC_S_SESSION, GUC_ACTION_SAVE, true,
- pg_hint_plan_parse_message);
+ pg_hint_plan_parse_messages);
}
return save_nestlevel;
LOAD 'pg_hint_plan';
SET pg_hint_plan.enable TO on;
SET pg_hint_plan.debug_print TO true;
+SET client_min_messages TO 'LOG';
EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id;
EXPLAIN (COSTS false) SELECT count(*) FROM t1, t2 WHERE t1.id = t2.id AND t1.id > 10;