All Products
Search
Document Center

PolarDB:pg_hint_plan

Last Updated:Mar 29, 2026

Ekstensi pg_hint_plan memungkinkan Anda mengganti pilihan rencana eksekusi dari pengoptimal kueri dengan menyisipkan petunjuk (hint) langsung dalam komentar SQL.

PolarDB for PostgreSQL (Compatible with Oracle) menggunakan cost-based optimizer yang memilih rencana eksekusi berdasarkan statistik data. Meskipun pengoptimal umumnya menghasilkan keputusan yang baik, ia tidak dapat mempertimbangkan setiap hubungan data. Mengatur variabel Grand Unified Configuration (GUC) menyesuaikan perilaku seluruh sesi, sedangkan pg_hint_plan hanya menargetkan satu kueri tanpa memengaruhi komponen lainnya.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

  • Kluster PolarDB for PostgreSQL (Compatible with Oracle)

  • Pengguna database dengan hak istimewa yang cukup untuk membuat ekstensi serta mengubah pengaturan pengguna atau database

Catatan penggunaan

  • Data Management Service (DMS) tidak mendukung komentar hint. Hubungkan ke database menggunakan klien lain.

  • pg_hint_plan hanya membaca blok komentar pertama dalam suatu kueri. Hint dalam blok komentar berikutnya akan diabaikan.

  • Selama penguraian hint, pemindai berhenti pada karakter apa pun selain huruf, angka, spasi, underscore (_), koma (,), atau tanda kurung (()).

  • pg_hint_plan membandingkan nama objek secara case-sensitive. Petunjuk yang mereferensikan TBL hanya berlaku untuk TBL, bukan tbl atau Tbl. Jika kueri menggunakan alias tabel, gunakan alias tersebut dalam hint—bukan nama tabel aslinya.

Batasan

Batasan berikut berlaku saat menggunakan pg_hint_plan dalam prosedur tersimpan PL/pgSQL:

  • Petunjuk hanya berlaku untuk jenis pernyataan berikut:

    • SELECT, INSERT, UPDATE, DELETE (kueri baris tunggal)

    • RETURN QUERY (kueri multi-baris)

    • EXECUTE QUERY (eksekusi Pernyataan SQL)

    • OPEN (membuka cursor)

    • FOR (traversal hasil kueri)

  • Tempatkan setiap hint tepat setelah kata pertama dalam kueri. Hint yang ditempatkan sebelum posisi tersebut tidak akan dikaitkan dengan kueri.

Instal ekstensi

  1. Buat ekstensi.

    CREATE EXTENSION pg_hint_plan;
  2. Muat ekstensi menggunakan salah satu metode berikut:

    For a single user:

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

    Ganti <username> dengan nama pengguna login.

    For a specific database:

    ALTER DATABASE <database_name> SET session_preload_libraries = 'pg_hint_plan';
    Catatan

    Jika kesalahan konfigurasi mencegah Anda masuk, sambungkan sebagai pengguna lain atau ke database lain, lalu atur ulang parameter tersebut:

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

    For a database cluster: Buka Quota Center. Pada baris untuk PolarDB PG pg_hint_plan use, klik Apply di kolom Actions.

  3. Verifikasi bahwa ekstensi berhasil dimuat.

    1. Aktifkan output debug.

      SET pg_hint_plan.debug_print TO on;
      SET pg_hint_plan.message_level TO notice;
    2. Jalankan kueri uji dengan hint.

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

      Output berikut mengonfirmasi bahwa ekstensi telah dimuat:

      NOTICE:  pg_hint_plan: used hint: Set(enable_seqscan 1)
    3. Nonaktifkan output debug.

      RESET pg_hint_plan.debug_print;
      RESET pg_hint_plan.message_level;

Tulis komentar hint

Komentar pg_hint_plan diawali dengan /*+ dan diakhiri dengan */. Setiap hint terdiri atas nama hint yang diikuti parameter dalam tanda kurung, dipisahkan oleh spasi. Untuk meningkatkan keterbacaan, letakkan beberapa hint pada baris terpisah.

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

Rencana kueri yang dihasilkan:

                                  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)

Jenis hint

Petunjuk metode pemindaian

Petunjuk metode pemindaian memaksa penggunaan metode pemindaian tertentu pada tabel target, yang diidentifikasi berdasarkan alias-nya jika tersedia.

Berlaku untuk: tabel standar, tabel turunan, tabel unlogged, tabel temporary, tabel sistem

Tidak berlaku untuk: tabel eksternal, fungsi tabel, pernyataan nilai konstan, common table expressions (CTEs), tampilan, subkueri

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

Petunjuk metode join

Petunjuk metode join memaksa penggunaan algoritma join tertentu untuk sekumpulan tabel.

Berlaku untuk: tabel standar, tabel turunan, tabel unlogged, tabel temporary, tabel eksternal, tabel sistem, fungsi tabel, perintah nilai konstan, CTEs

Tidak berlaku untuk: tampilan, subkueri

Petunjuk urutan join

Petunjuk urutan join menentukan urutan tabel saat dilakukan join. Dua bentuk sintaks didukung:

  • Leading(t1 t2 t3) — hanya menentukan urutan join tanpa membatasi arah pada setiap level

  • Leading((t1 t2) t3) — menentukan urutan sekaligus arah join (tanda kurung bersarang menunjukkan pasangan join)

/*+
    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);

Dalam contoh ini:

  • NestLoop(t1 t2) — menggunakan nested loop join untuk t1 dan t2

  • MergeJoin(t1 t2 t3) — menggunakan merge join untuk hasil join (t1, t2) yang kemudian di-join dengan t3

  • Leading(t1 t2 t3) — melakukan join ketiga tabel dalam urutan t1 → t2 → t3

Petunjuk koreksi jumlah baris

Petunjuk koreksi jumlah baris mengganti estimasi jumlah baris yang digunakan pengoptimal untuk hasil join. Petunjuk ini berguna ketika statistik pengoptimal tidak akurat.

/*+ Rows(a b #10) */ SELECT ...; -- Tetapkan hasil join menjadi tepat 10 baris
/*+ Rows(a b +10) */ SELECT ...; -- Tambahkan 10 ke estimasi jumlah baris
/*+ Rows(a b -10) */ SELECT ...; -- Kurangi 10 dari estimasi jumlah baris
/*+ Rows(a b *10) */ SELECT ...; -- Kalikan estimasi jumlah baris dengan 10

Petunjuk eksekusi paralel

Petunjuk eksekusi paralel mengontrol tingkat paralelisme untuk suatu kueri.

Berlaku untuk: tabel standar, tabel turunan, tabel unlogged, tabel sistem. Tabel internal dalam tampilan dapat ditargetkan berdasarkan nama asli atau alias-nya.

Tidak berlaku untuk: tabel eksternal, klausa konstan, CTEs, tampilan, subkueri

Contoh 1: Atur paralelisme untuk dua tabel dalam join.

EXPLAIN /*+ Parallel(c1 3 hard) Parallel(c2 5 hard) */
       SELECT c2.a FROM c1 JOIN c2 ON (c1.a = c2.a);

Output:

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)

Contoh 2: Atur paralelisme untuk agregasi tabel tunggal.

EXPLAIN /*+ Parallel(tl 5 hard) */ SELECT sum(a) FROM tl;

Output:

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)

Petunjuk parameter GUC

Petunjuk parameter GUC mengubah nilai parameter GUC hanya selama pembuatan rencana kueri. Perubahan ini tidak memengaruhi pernyataan lain. Jika parameter GUC yang sama muncul beberapa kali, nilai terakhir yang berlaku.

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

Referensi hint

Tabel berikut mencantumkan semua format hint yang didukung. Tanda kurung siku [ ] menunjukkan parameter opsional.

JenisFormatDeskripsi
Metode pemindaianSeqScan(table)Memaksa pemindaian sekuensial pada tabel.
TidScan(table)Memaksa pemindaian TID pada tabel.
IndexScan(table [index...])Memaksa pemindaian indeks. Secara opsional tentukan indeks mana yang akan digunakan.
IndexOnlyScan(table [index...])Memaksa pemindaian hanya-indeks. Secara opsional tentukan indeks mana yang akan digunakan.
BitmapScan(table [index...])Memaksa pemindaian indeks bitmap. Secara opsional tentukan indeks mana yang akan digunakan.
NoSeqScan(table)Mencegah pemindaian sekuensial.
NoTidScan(table)Mencegah pemindaian TID.
NoIndexScan(table)Mencegah pemindaian indeks.
NoIndexOnlyScan(table)Mencegah pemindaian hanya-indeks.
NoBitmapScan(table)Mencegah pemindaian indeks bitmap.
Metode joinNestLoop(table table [table...])Memaksa join nested loop.
HashJoin(table table [table...])Memaksa join hash.
MergeJoin(table table [table...])Memaksa join merge.
NoNestLoop(table table [table...])Mencegah join nested loop.
NoHashJoin(table table [table...])Mencegah join hash.
NoMergeJoin(table table [table...])Mencegah join merge.
Urutan joinLeading(table table [table...])Menentukan urutan join (hanya urutan, tanpa batasan arah).
Leading(<join pair>)Menentukan urutan dan arah join menggunakan tanda kurung bersarang.
Koreksi jumlah barisRows(table table [table...] correction)Mengoreksi estimasi jumlah baris untuk join. Metode koreksi: #<n> (tetapkan), +<n> (tambah), -<n> (kurang), *<n> (kali).
Kueri paralelParallel(table <# of workers> [soft|hard])Mengontrol pemindaian paralel untuk tabel yang ditentukan. Atur <# of workers> ke 0 untuk menonaktifkan eksekusi paralel. soft (default) menyesuaikan max_parallel_workers_per_gather dan membiarkan pengoptimal menentukan tingkat akhir. hard memaksa tingkat yang ditentukan.
PX(<# of workers>)Menentukan tingkat paralelisme untuk eksekusi paralel lintas node.
NoPX()Menonaktifkan eksekusi paralel lintas node untuk kueri.
Parameter GUCSet(GUC-param value)Menetapkan parameter GUC ke nilai yang ditentukan selama pembuatan rencana kueri.
Catatan

Dalam skenario eksekusi paralel lintas node:

  • Petunjuk koreksi jumlah baris tidak didukung.

  • Petunjuk metode join hanya berlaku untuk join antara dua tabel.

  • Petunjuk urutan join hanya dapat menentukan urutan join keseluruhan untuk semua tabel.