ヒントテーブル

ヒントは特別な形式のコメント内に記載されていますがクエリを編集できない場合には不便です。このような場合には "hint_plan.hints" という名前の特別なテーブルにヒントを置くことができます。このテーブルは以下のカラムで構成されています。

列名

説明

id

ユーザがヒントの行を識別するためのユニークな番号です。
この列はシーケンスによって自動的に埋められます。

query_id

A unique query ID, generated by the backend when the GUC compute_query_id is enabled

application_name

ヒントの適用対象のアプリケーション名を指定します。
下記の例ではpsqlから実行されたクエリのみがヒントの適用対象となります。
全てのアプリケーションにヒントを適用したいときは、空文字列を登録します。

hints

ヒント句を指定します。
コメントの記号を除いたヒントのみを登録します。

以下の例はヒントテーブルの操作方法を示しています。

=# EXPLAIN (VERBOSE, COSTS false) SELECT * FROM t1 WHERE t1.id = 1;
               QUERY PLAN
----------------------------------------
 Seq Scan on public.t1
   Output: id, id2
   Filter: (t1.id = 1)
 Query Identifier: -7164653396197960701
(4 rows)
=# INSERT INTO hint_plan.hints(query_id, application_name, hints)
     VALUES (-7164653396197960701, '', 'SeqScan(t1)');
INSERT 0 1
=# UPDATE hint_plan.hints
     SET hints = 'IndexScan(t1)'
     WHERE id = 1;
UPDATE 1
=# DELETE FROM hint_plan.hints WHERE id = 1;
DELETE 1

ヒントテーブルは拡張機能の所有者が所有し、拡張機能作成時におけるデフォルトの権限を持ちます。ヒントテーブル内のヒントはコメント内のヒントよりも優先されます。

The query ID can be retrieved with pg_stat_statements or with EXPLAIN (VERBOSE).

ヒントの種類

Hinting phrases are classified in multiple types based on what kind of object and how they can affect the planner. See Hint list for more details.

スキャン方法

スキャン方法のヒントは、対象のテーブルに対して特定のスキャン方法を強制するものです。pg_hint_planは対象のテーブルに別名が存在する場合、別名で認識します。この種類の例はSeqScanIndexScanなどです。

スキャン方法のヒントは、通常のテーブル・継承テーブル・UNLOGGEDテーブル・一時テーブル・システムカタログに効果があります。外部テーブル・テーブル関数・VALUES句・CTE・ビュー・副問い合わせには影響を与えません。

=# /*+
     SeqScan(t1)
     IndexScan(t2 t2_pkey)
    */
   SELECT * FROM table1 t1 JOIN table table2 t2 ON (t1.key = t2.key);

結合方法

結合方法のヒントは、指定したテーブルを含む結合の結合方法を強制するものです。

これは、通常のテーブル・継承テーブル・UNLOGGEDテーブル・一時テーブル・外部テーブル・システムカタログ・テーブル関数・VALUESコマンド結果、およびパラメータリストに含めることが許可されているCTEの結合にのみ影響を与えます。しかし、ビュー・副問い合わせの結合には影響を与えません。

結合順

Leadingヒントは、2つ以上のテーブルの結合順を強制するものです。強制には2つの方法があります。1つは特定の結合順を強制し各結合レベルでは方向を制限しない方法です。もう1つは結合の方向を追加で指定するものです。詳細はヒント一覧で確認してください。以下は例です。

=# /*+
     NestLoop(t1 t2)
     MergeJoin(t1 t2 t3)
     Leading(t1 t2 t3)
    */
   SELECT * FROM table1 t1
     JOIN table table2 t2 ON (t1.key = t2.key)
     JOIN table table3 t3 ON (t2.key = t3.key);

行数補正

Rowsヒントは、プランナの制限に起因する結合の見積り行数誤りを修正します。以下は例です。

=# /*+ Rows(a b #10) */ SELECT... ; Sets rows of join result to 10
=# /*+ Rows(a b +10) */ SELECT... ; Increments row number by 10
=# /*+ Rows(a b -10) */ SELECT... ; Subtracts 10 from the row number.
=# /*+ Rows(a b *10) */ SELECT... ; Makes the number 10 times larger.

パラレルプラン

Parallelヒント は、スキャンの並列実行の設定を強制するものです。第3パラメータは強制の強さを指定します。softpg_hint_planmax_parallel_worker_per_gather を変更するだけで、その他のすべてはプランナに任せることを意味します。hardはプランナのパラメータを変更し、強制的にその数値を適用するようにします。 このヒントは通常のテーブル・継承の親テーブル・UNLOGGEDテーブル・システムカタログに影響を与えることができます。外部テーブル・テーブル関数・VALUE句・CTE・ビュー・サブクエリには影響を与えません。 ビューの内部テーブルについては、対象オブジェクトとして実名/別名を用いて指定できます。次の例のクエリは、各テーブルで異なる設定を強制しています。

=# EXPLAIN /*+ Parallel(c1 3 hard) Parallel(c2 5 hard) */
   SELECT c2.a FROM c1 JOIN c2 ON (c1.a = c2.a);
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Hash Join  (cost=2.86..11406.38 rows=101 width=4)
   Hash Cond: (c1.a = c2.a)
   ->  Gather  (cost=0.00..7652.13 rows=1000101 width=4)
         Workers Planned: 3
         ->  Parallel Seq Scan on c1  (cost=0.00..7652.13 rows=322613 width=4)
   ->  Hash  (cost=1.59..1.59 rows=101 width=4)
         ->  Gather  (cost=0.00..1.59 rows=101 width=4)
               Workers Planned: 5
               ->  Parallel Seq Scan on c2  (cost=0.00..1.59 rows=59 width=4)

=# EXPLAIN /*+ Parallel(tl 5 hard) */ SELECT sum(a) FROM tl;
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Finalize Aggregate  (cost=693.02..693.03 rows=1 width=8)
   ->  Gather  (cost=693.00..693.01 rows=5 width=8)
         Workers Planned: 5
         ->  Partial Aggregate  (cost=693.00..693.01 rows=1 width=8)
               ->  Parallel Seq Scan on tl  (cost=0.00..643.00 rows=20000 width=4)

プランニング中のGUCパラメータの設定

Setヒントはプランニング中のみGUCパラメータを変更します。 Query Planning で示したGUCパラメータは、他のヒントがプランナの設定パラメータと競合しない限り、期待される効果を発揮することができます。同じGUCパラメータに関するヒントのうち、最後のものが効果を発揮します。pg_hint_planのGUCパラメータ もこのヒントで設定可能ですが期待通りには動作しません。詳しくは機能的な制限事項を参照してください。

=# /*+ Set(random_page_cost 2.0) */
   SELECT * FROM table1 t1 WHERE key = 'value';
...

pg_hint_planのGUCパラメータ

以下のGUCパラメータはpg_hint_planの動作を制御します。

パラメータ名

説明

デフォルト値

pg_hint_plan.enable_hint

Trueはpg_hint_planを有効にします。

on

pg_hint_plan.enable_hint_table

Trueはテーブルによってヒントを指定する機能を有効にします。

off

pg_hint_plan.parse_messages

指定したヒントを構文解析できなかった場合のログメッセージのレベルを指定します。指定可能な値は、errorwarningnoticeinfologdebugです。

INFO

pg_hint_plan.debug_print

動作状況を示すログメッセージの出力を制御します。指定可能な値は offondetailedverboseです。

off

pg_hint_plan.message_level

動作ログメッセージのログレベルを指定します。指定可能な値は、errorwarningnoticeinfologdebugです。

INFO