すべてのプロダクト
Search
ドキュメントセンター

PolarDB:pg_hint_plan

最終更新日:Mar 29, 2026

pg_hint_plan 拡張は、SQL コメント内にヒントを直接埋め込むことで、クエリ オプティマイザーの実行計画選択をオーバーライドできます。

PolarDB for PostgreSQL (Compatible with Oracle) では、統計データに基づいて実行計画を選択するコストベースオプティマイザが採用されています。このオプティマイザーは一般的に適切な選択を行いますが、すべてのデータ関係を考慮することはできません。Grand Unified Configuration (GUC) 変数を設定すると、セッション全体の動作が変更されますが、pg_hint_plan は単一のクエリのみに適用され、他の処理には一切影響を与えません。

前提条件

開始する前に、以下の条件を満たしていることを確認してください。

  • PolarDB for PostgreSQL (Compatible with Oracle) クラスター

  • 拡張の作成およびユーザーまたはデータベース設定の変更に十分な権限を持つデータベースユーザー

注意事項

  • Data Management Service (DMS) ではヒントコメントがサポートされていません。別のクライアントを使用してデータベースに接続してください。

  • pg_hint_plan はクエリ内の最初のコメントブロックのみを読み取ります。その後のコメントブロック内のヒントは無視されます。

  • ヒントの解析中、スキャナーは英字、数字、空白、アンダースコア (_)、カンマ (,)、または括弧 (()) 以外の文字に到達すると停止します。

  • pg_hint_plan ではオブジェクト名の比較が大文字小文字を区別します。TBL を参照するヒントは、TBL のみに適用され、tblTbl には適用されません。クエリでテーブルエイリアスが使用されている場合、ヒントでは元のテーブル名ではなくエイリアスを使用してください。

制限事項

PL/pgSQL ストアドプロシージャ内で pg_hint_plan を使用する場合、以下の制限が適用されます。

  • ヒントが有効になるステートメントの種類は以下のとおりです。

    • SELECTINSERTUPDATEDELETE(単一行クエリ)

    • RETURN QUERY(複数行クエリ)

    • EXECUTE QUERY(SQL ステートメントの実行)

    • OPEN(カーソルのオープン)

    • FOR(クエリ結果の走査)

  • 各ヒントはクエリの先頭の単語直後に配置してください。それより前の位置に配置されたヒントは、対象のクエリに関連付けられません。

拡張のインストール

  1. 拡張を作成します。

    CREATE EXTENSION pg_hint_plan;
  2. 以下のいずれかの方法で拡張をロードします。

    単一ユーザー向け:

    ALTER USER <username> SET session_preload_libraries = 'pg_hint_plan';

    <username> をログインユーザー名に置き換えてください。

    特定のデータベース向け:

    ALTER DATABASE <database_name> SET session_preload_libraries = 'pg_hint_plan';
    説明

    構成エラーによりログインできない場合は、別のユーザーまたは別のデータベースに接続し、パラメーターをリセットしてください。

    ALTER USER <username> RESET session_preload_libraries;
    ALTER DATABASE <database_name> RESET session_preload_libraries;

    データベースクラスターの場合: クォータセンター に移動します。PolarDB PG Pg_hint_plan 使用 の行で、申請 をクリックします(操作 列)。

  3. 拡張が正常にロードされたことを確認します。

    1. デバッグ出力を有効化します。

      SET pg_hint_plan.debug_print TO on;
      SET pg_hint_plan.message_level TO notice;
    2. ヒント付きのテストクエリを実行します。

      /*+Set(enable_seqscan 1)*/SELECT 1;

      以下の出力が表示された場合、拡張が正常にロードされたことを確認できます。

      NOTICE:  pg_hint_plan: used hint: Set(enable_seqscan 1)
    3. デバッグ出力を無効化します。

      RESET pg_hint_plan.debug_print;
      RESET pg_hint_plan.message_level;

ヒントコメントの記述

pg_hint_plan のコメントは /*+ で始まり、*/ で終了します。各ヒントは、括弧付きのパラメーターを伴うヒント名から構成され、複数のヒントは可読性向上のため改行で区切って記述します。

/*+
   HashJoin(a b)
   SeqScan(a)
 */
EXPLAIN SELECT *
   FROM pgbench_branches b
   JOIN pgbench_accounts a ON b.bid = a.bid
   ORDER BY a.aid;

生成されるクエリプランは以下のとおりです。

                                  QUERY PLAN
---------------------------------------------------------------------------------------
 Sort  (cost=31465.84..31715.84 rows=100000 width=197)
   Sort Key: a.aid
   ->  Hash Join  (cost=1.02..4016.02 rows=100000 width=197)
         Hash Cond: (a.bid = b.bid)
         ->  Seq Scan on pgbench_accounts a  (cost=0.00..2640.00 rows=100000 width=97)
         ->  Hash  (cost=1.01..1.01 rows=1 width=100)
               ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=100)
(7 rows)

ヒントの種類

スキャン方式ヒント

スキャン方式ヒントは、存在する場合はエイリアスによって識別される対象テーブルに対して特定のスキャン方式を強制します。

有効な対象:標準テーブル、継承テーブル、非ログテーブル、一時テーブル、システムテーブル

無効な対象:外部テーブル、テーブル関数、定数値ステートメント、共通テーブル式(CTE)、ビュー、サブクエリ

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

結合方式ヒント

結合方式ヒントは、一連のテーブルに対して特定の結合アルゴリズムを強制します。

有効な対象:標準テーブル、継承テーブル、非ログテーブル、一時テーブル、外部テーブル、システムテーブル、テーブル関数、定数値コマンド、CTE

無効な対象:ビュー、サブクエリ

結合順序ヒント

結合順序ヒントは、テーブルが結合される順序を指定します。2 種類の構文形式がサポートされています。

  • Leading(t1 t2 t3) — 結合順序のみを指定し、各レベルでの方向を制約しません。

  • Leading((t1 t2) t3) — 順序と方向の両方を指定します(ネストされた括弧は結合ペアを示します)。

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

この例では、以下のとおりです。

  • NestLoop(t1 t2) — t1 と t2 の間でネステッドループ結合を使用します。

  • MergeJoin(t1 t2 t3) — (t1, t2) の結合結果と t3 の間でマージ結合を使用します。

  • Leading(t1 t2 t3) — 3 つのテーブルを t1 → t2 → t3 の順で結合します。

行数補正ヒント

行数補正ヒントは、結合結果に対してオプティマイザーが使用する行数推定値を上書きします。これは、オプティマイザーの統計情報が不正確な場合に有効です。

/*+ Rows(a b #10) */ SELECT ...; -- 結合結果を正確に 10 行に設定
/*+ Rows(a b +10) */ SELECT ...; -- 推定行数に 10 を加算
/*+ Rows(a b -10) */ SELECT ...; -- 推定行数から 10 を減算
/*+ Rows(a b *10) */ SELECT ...; -- 推定行数を 10 倍に設定

並列実行ヒント

並列実行ヒントは、クエリの並列処理の次数を制御します。

有効な対象:標準テーブル、継承テーブル、非ログテーブル、システムテーブル。ビューの内部テーブルは、実際の名前またはエイリアスで指定できます。

無効な対象:外部テーブル、定数句、CTE、ビュー、サブクエリ

例 1:結合における 2 つのテーブルの並列処理を設定します。

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)

例 2:単一テーブル集約の並列処理を設定します。

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 パラメーター ヒント

GUC パラメーター ヒントは、クエリプラン生成時のみ GUC パラメーターの値を変更します。この変更は他のステートメントには影響しません。同一の GUC パラメーターが複数回出現した場合、最後に指定された値が有効になります。

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

ヒント リファレンス

以下の表に、サポートされるすべてのヒントフォーマットを示します。角括弧 [ ] で囲まれた項目は省略可能です。

種類フォーマット説明
スキャン方式SeqScan(table)テーブルに対してシーケンシャルスキャンを強制します。
TidScan(table)テーブルに対して TID スキャンを強制します。
IndexScan(table [index...])インデックススキャンを強制します。必要に応じて使用するインデックスを指定できます。
IndexOnlyScan(table [index...])インデックスのみスキャンを強制します。必要に応じて使用するインデックスを指定できます。
BitmapScan(table [index...])ビットマップ索引スキャンを強制します。必要に応じて使用するインデックスを指定できます。
NoSeqScan(table)シーケンシャルスキャンを禁止します。
NoTidScan(table)TID スキャンを禁止します。
NoIndexScan(table)インデックススキャンを禁止します。
NoIndexOnlyScan(table)インデックスのみスキャンを禁止します。
NoBitmapScan(table)ビットマップ索引スキャンを禁止します。
結合方式NestLoop(table table [table...])ネステッドループ結合を強制します。
HashJoin(table table [table...])ハッシュ結合を強制します。
MergeJoin(table table [table...])マージ結合を強制します。
NoNestLoop(table table [table...])ネステッドループ結合を禁止します。
NoHashJoin(table table [table...])ハッシュ結合を禁止します。
NoMergeJoin(table table [table...])マージ結合を禁止します。
結合順序Leading(table table [table...])結合順序を指定します(順序のみ、方向制約なし)。
Leading(<join pair>)ネストされた括弧を使用して結合順序と方向を指定します。
行数補正Rows(table table [table...] correction)結合の行数推定値を補正します。補正方法: #<n>(設定)、+<n>(加算)、-<n>(減算)、*<n>(乗算)。
並列クエリParallel(table <# of workers> [soft|hard])指定されたテーブルの並列スキャンを制御します。<# of workers>0 に設定すると並列実行が無効になります。soft(デフォルト)では max_parallel_workers_per_gather を調整し、最終的な並列処理の次数はオプティマイザーが決定します。hard では指定された次数を強制します。
PX(<# of workers>)ノード間並列実行 の並列処理の次数を指定します。
NoPX()クエリに対するノード間並列実行を無効化します。
GUC パラメーターSet(GUC-param value)クエリプラン生成中に GUC パラメーターを指定された値に設定します。
説明

ノード間並列実行シナリオでは:

  • 行数補正ヒントはサポートされていません。

  • 結合方式ヒントは、2 つのテーブル間の結合にのみ適用されます。

  • 結合順序ヒントは、すべてのテーブルの全体的な結合順序のみを指定できます。