Membuat dan mengelola saran bernama

Untuk mengontrol cara perencana kueri AlloyDB untuk PostgreSQL menghasilkan rencana eksekusi tanpa mengubah kueri aplikasi, Anda dapat membuat, memverifikasi, melihat, mengaktifkan, menonaktifkan, dan menghapus petunjuk bernama. Petunjuk bernama mengaitkan kueri dengan sekumpulan petunjuk yang menentukan detail rencana eksekusi yang diinginkan. Saat perencana kueri membuat rencana eksekusi untuk kueri terkait, perencana kueri akan menerapkan petunjuk dan otomatis menerapkannya kembali pada eksekusi kueri berikutnya. Misalnya, Anda dapat menggunakan petunjuk bernama untuk memaksa pemindaian indeks, bukan pemindaian berurutan pada tabel, atau untuk menerapkan urutan gabungan tertentu di beberapa tabel.

Petunjuk bernama di AlloyDB mendukung semua petunjuk dari ekstensi pg_hint_plan open source dan petunjuk berikut untuk columnar engine:

  • ColumnarScan(table): memaksa pemindaian berbasis kolom pada tabel.

  • NoColumnarScan(table): menonaktifkan pemindaian berbasis kolom pada tabel.

AlloyDB memungkinkan Anda membuat petunjuk bernama untuk kueri berparameter dan kueri non-parameter, yang dalam dokumen ini disebut sebagai kueri peka parameter.

Alur kerja

Penggunaan petunjuk bernama melibatkan langkah-langkah berikut:

  1. Identifikasi kueri yang ingin Anda buatkan petunjuk bernama.

  2. Buat petunjuk bernama dengan petunjuk yang akan diterapkan saat kueri dijalankan berikutnya.

  3. Verifikasi penerapan petunjuk bernama.

Halaman ini menggunakan tabel dan indeks berikut untuk contoh:

CREATE TABLE t(a INT, b INT);
CREATE INDEX t_idx1 ON t(a);
  DROP EXTENSION IF EXISTS google_auto_hints;

Untuk terus menggunakan petunjuk bernama yang Anda buat menggunakan versi sebelumnya, buat ulang petunjuk tersebut dengan mengikuti petunjuk di halaman ini.

Sebelum memulai

  • Aktifkan fitur petunjuk bernama di instance Anda. Tetapkan flag alloydb.enable_named_hints ke on. Anda dapat mengaktifkan flag ini di tingkat seluruh server atau di tingkat sesi. Untuk meminimalkan overhead yang mungkin timbul akibat penggunaan fitur ini, aktifkan flag ini hanya di tingkat sesi.

    Untuk mengetahui informasi selengkapnya, lihat Mengonfigurasi flag database instance.

    Untuk memastikan flag diaktifkan, jalankan perintah show alloydb.enable_named_hints;. Jika tanda diaktifkan, output akan menampilkan "on".

  • Untuk setiap database tempat Anda ingin menggunakan petunjuk bernama, buat ekstensi di database dari instance utama AlloyDB sebagai pengguna alloydbsuperuser atau postgres:

    CREATE EXTENSION google_auto_hints CASCADE;
    

Peran yang diperlukan

Untuk mendapatkan izin yang diperlukan untuk membuat dan mengelola petunjuk bernama, minta administrator untuk memberi Anda peran Identity and Access Management (IAM) berikut:

Meskipun izin default hanya mengizinkan pengguna dengan peran alloydbsuperuser untuk membuat petunjuk bernama, Anda dapat memberikan izin tulis kepada pengguna atau peran lain dari database agar mereka dapat membuat petunjuk bernama.

GRANT INSERT,DELETE,UPDATE ON hint_plan.plan_patches, hint_plan.hints TO role_name;
GRANT USAGE ON SEQUENCE hint_plan.hints_id_seq, hint_plan.plan_patches_id_seq TO role_name;

Mengidentifikasi kueri

Anda dapat menggunakan ID kueri untuk mengidentifikasi kueri yang rencana default-nya perlu disesuaikan. ID kueri akan tersedia setelah setidaknya satu eksekusi kueri.

Gunakan metode berikut untuk mengidentifikasi ID kueri:

  • Jalankan perintah EXPLAIN (VERBOSE), seperti yang ditunjukkan dalam contoh berikut:

    EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 99;
                            QUERY PLAN
    ----------------------------------------------------------
    Seq Scan on public.t  (cost=0.00..38.25 rows=11 width=8)
      Output: a, b
      Filter: (t.a = 99)
    Query Identifier: -6875839275481643436
    

    Dalam output, ID kuerinya adalah -6875839275481643436.

  • Buat kueri tampilan pg_stat_statements.

    Jika Anda mengaktifkan ekstensi pg_stat_statements, Anda dapat menemukan ID kueri dengan membuat kueri tampilan pg_stat_statements, seperti yang ditunjukkan dalam contoh berikut:

    select query, queryid from pg_stat_statements;
    

Membuat petunjuk bernama

Untuk membuat petunjuk bernama, gunakan fungsi google_create_named_hints(), yang membuat pengaitan antara kueri dan petunjuk dalam database.

SELECT google_create_named_hints(
HINTS_NAME=>'HINTS_NAME',
SQL_ID=>QUERY_ID,
SQL_TEXT=>QUERY_TEXT,
APPLICATION_NAME=>'APPLICATION_NAME',
HINTS=>'HINTS',
DISABLED=>DISABLED);

Ganti kode berikut:

  • HINTS_NAME: nama untuk petunjuk bernama. ID ini harus unik dalam database.
  • SQL_ID (Opsional): ID kueri dari kueri yang Anda buat petunjuk bernama.

    Anda dapat menggunakan ID kueri atau teks kueri—parameter SQL_TEXT—untuk membuat petunjuk bernama. Namun, sebaiknya gunakan ID kueri untuk membuat petunjuk bernama karena AlloyDB otomatis menemukan teks kueri yang dinormalisasi berdasarkan ID kueri.

  • SQL_TEXT (Opsional): teks kueri dari kueri yang petunjuk bernama-nya Anda buat.

    Saat Anda menggunakan teks kueri, teks tersebut harus sama dengan kueri yang dimaksud, kecuali untuk nilai literal dan konstanta dalam kueri. Ketidakcocokan apa pun, termasuk perbedaan huruf besar/kecil, dapat menyebabkan petunjuk bernama tidak diterapkan. Untuk mempelajari cara membuat petunjuk bernama untuk kueri dengan literal dan konstanta, lihat Membuat petunjuk bernama yang sensitif terhadap parameter.

  • APPLICATION_NAME (Opsional): nama aplikasi klien sesi yang ingin Anda gunakan petunjuk bernama. String kosong memungkinkan Anda menerapkan petunjuk bernama ke kueri, terlepas dari aplikasi klien yang mengeluarkan kueri.

  • HINTS: daftar petunjuk yang dipisahkan spasi untuk kueri.

  • DISABLED (Opsional): BOOL. Jika TRUE, awalnya membuat petunjuk bernama sebagai dinonaktifkan.

Contoh:

SELECT google_create_named_hints(
HINTS_NAME=>'my_hint1',
SQL_ID=>-6875839275481643436,
SQL_TEXT=>NULL,
APPLICATION_NAME=>'',
HINTS=>'IndexScan(t)',
DISABLED=>NULL);

Kueri ini membuat petunjuk bernama my_hint1. Petunjuknya, IndexScan(t), diterapkan oleh perencana untuk memaksa pemindaian indeks pada tabel t pada eksekusi berikutnya dari contoh kueri ini.

Setelah membuat petunjuk bernama, Anda dapat menggunakan google_named_hints_view untuk mengonfirmasi apakah petunjuk bernama telah dibuat, seperti yang ditunjukkan dalam contoh berikut:

postgres=>\x
postgres=>select * from google_named_hints_view limit 1;
-[ RECORD 1 ]-----+-----------------------------
hints_name | my_hint1
sql_id | -6875839275481643436
id | 9
query_string | SELECT * FROM t WHERE a = ?;
application_name |
hints | IndexScan(t)
disabled | f

Setelah petunjuk bernama dibuat di instance utama, petunjuk tersebut akan otomatis diterapkan ke kueri terkait di instance kumpulan baca, asalkan Anda juga mengaktifkan fitur petunjuk bernama di instance kumpulan baca.

Membuat petunjuk bernama yang sensitif terhadap parameter

Secara default, saat petunjuk bernama dibuat untuk kueri, teks kueri terkait akan dinormalisasi dengan mengganti nilai literal dan konstanta dalam teks kueri dengan penanda parameter, seperti ?. Petunjuk bernama kemudian digunakan untuk kueri yang dinormalisasi tersebut, meskipun dengan nilai yang berbeda untuk penanda parameter.

Misalnya, menjalankan kueri berikut memungkinkan kueri lain, seperti SELECT * FROM t WHERE a = 99;, menggunakan petunjuk bernama my_hint2 secara default.

SELECT google_create_named_hints(
  HINTS_NAME=>'my_hint2',
  SQL_ID=>NULL,
  SQL_TEXT=>'SELECT * FROM t WHERE a = ?;',
  APPLICATION_NAME=>'',
  HINTS=>'SeqScan(t)',
  DISABLED=>NULL);

Kemudian, kueri, seperti SELECT * FROM t WHERE a = 99;, dapat menggunakan petunjuk bernama my_hint2 secara default.

AlloyDB juga memungkinkan Anda membuat petunjuk bernama untuk teks kueri yang tidak berparameter, dengan setiap nilai literal dan konstanta dalam teks kueri menjadi signifikan saat mencocokkan kueri.

Saat Anda menerapkan petunjuk bernama yang sensitif terhadap parameter, dua kueri yang hanya berbeda dalam nilai literal atau konstanta yang sesuai juga dianggap berbeda. Jika ingin menerapkan rencana untuk kedua kueri, Anda harus membuat petunjuk bernama terpisah untuk setiap kueri. Namun, Anda dapat menggunakan petunjuk yang berbeda untuk dua petunjuk bernama.

Untuk membuat petunjuk bernama yang sensitif terhadap parameter, tetapkan parameter SENSITIVE_TO_PARAM dari fungsi google_create_named_hints() ke TRUE, seperti yang ditunjukkan dalam contoh berikut:

SELECT google_create_named_hints(
HINTS_NAME=>'my_hint3',
SQL_ID=>NULL,
SQL_TEXT=>'SELECT * FROM t WHERE a = 88;',
APPLICATION_NAME=>'',
HINTS=>'IndexScan(t)',
DISABLED=>NULL,
SENSITIVE_TO_PARAM=>TRUE);

Kueri SELECT * FROM t WHERE a = 99; tidak dapat menggunakan petunjuk bernama my_hint3, karena nilai literal "99" tidak cocok dengan "88".

Saat Anda menggunakan petunjuk bernama yang sensitif terhadap parameter, pertimbangkan hal berikut:

  • Petunjuk bernama yang sensitif terhadap parameter tidak mendukung campuran nilai literal dan konstanta serta penanda parameter dalam teks kueri.
  • Saat Anda membuat petunjuk bernama yang sensitif terhadap parameter dan petunjuk bernama default untuk kueri yang sama, petunjuk bernama yang sensitif terhadap parameter lebih diutamakan daripada petunjuk bernama default.
  • Jika Anda ingin menggunakan ID kueri untuk membuat petunjuk bernama yang sensitif terhadap parameter, pastikan kueri dijalankan dalam sesi saat ini. Nilai parameter dari eksekusi terbaru (dalam sesi saat ini) digunakan untuk membuat petunjuk bernama.

Memverifikasi penerapan petunjuk bernama

Setelah Anda membuat petunjuk bernama, gunakan metode berikut untuk memverifikasi bahwa rencana kueri dipaksakan sebagaimana mestinya.

  • Gunakan perintah EXPLAIN atau perintah EXPLAIN (ANALYZE).

    Untuk melihat petunjuk yang coba diterapkan oleh perencana, Anda dapat menetapkan flag berikut di tingkat sesi sebelum menjalankan perintah EXPLAIN:

    SET pg_hint_plan.debug_print = ON;
    SET client_min_messages = LOG;
    
  • Gunakan ekstensi auto_explain.

Mengelola petunjuk bernama

AlloyDB memungkinkan Anda melihat, mengaktifkan dan menonaktifkan, serta menghapus petunjuk bernama.

Melihat petunjuk bernama

Untuk melihat petunjuk bernama yang ada, gunakan fungsi google_named_hints_view, seperti yang ditunjukkan dalam contoh berikut:

postgres=>\x
postgres=>select * from google_named_hints_view limit 1;
-[ RECORD 1 ]-----+-----------------------------
hints_name | my_hint1
sql_id | -6875839275481643436
id | 9
query_string | SELECT * FROM t WHERE a = ?;
application_name |
hints | IndexScan(t)
disabled | f

Mengaktifkan petunjuk bernama

Untuk mengaktifkan petunjuk bernama yang ada, gunakan fungsi google_enable_named_hints(HINTS_NAME). Secara default, petunjuk bernama diaktifkan saat Anda membuatnya.

Misalnya, untuk mengaktifkan kembali petunjuk bernama my_hint1 yang sebelumnya dinonaktifkan dari database, jalankan fungsi berikut:

SELECT google_enable_named_hints('my_hint1');

Menonaktifkan petunjuk bernama

Untuk menonaktifkan petunjuk bernama yang ada, gunakan fungsi google_disable_named_hints(HINTS_NAME).

Misalnya, untuk menghapus contoh petunjuk bernama my_hint1 dari database, jalankan fungsi berikut:

SELECT google_disable_named_hints('my_hint1');

Menghapus petunjuk bernama

Untuk menghapus petunjuk bernama, gunakan fungsi google_delete_named_hints(HINTS_NAME).

Misalnya, untuk menghapus contoh petunjuk bernama my_hint1 dari database, jalankan fungsi berikut:

SELECT google_delete_named_hints('my_hint1');

Menonaktifkan fitur petunjuk bernama

Untuk menonaktifkan fitur petunjuk bernama di instance Anda, tetapkan flag alloydb.enable_named_hints ke off. Untuk mengetahui informasi selengkapnya, lihat Mengonfigurasi flag database instance.

Batasan

Penggunaan petunjuk bernama memiliki batasan berikut:

  • Saat Anda menggunakan ID kueri untuk membuat petunjuk bernama, teks kueri asli memiliki batasan panjang 2.048 karakter.
  • Mengingat semantik kueri yang kompleks, tidak semua petunjuk dan kombinasinya dapat diterapkan sepenuhnya. Sebaiknya uji petunjuk yang diinginkan pada kueri Anda sebelum men-deploy petunjuk bernama dalam produksi.
  • Pemaksaan urutan gabungan untuk kueri kompleks dibatasi.
  • Menggunakan petunjuk bernama untuk memengaruhi pemilihan rencana dapat mengganggu peningkatan pengoptimal AlloyDB di masa mendatang. Pastikan Anda meninjau kembali pilihan penggunaan petunjuk bernama dan menyesuaikan petunjuk bernama saat peristiwa berikut terjadi:

    • Ada perubahan signifikan pada workload.
    • Peluncuran atau upgrade AlloyDB baru yang melibatkan perubahan dan peningkatan pengoptimal tersedia.
    • Metode penyesuaian kueri lainnya diterapkan ke kueri yang sama.
    • Penggunaan petunjuk bernama menambah overhead yang signifikan pada performa sistem.

Untuk mengetahui informasi selengkapnya tentang batasan, lihat dokumentasi pg_hint_plan.

Langkah Berikutnya