Fitur Outline di PolarDB for PostgreSQL (kompatibel dengan Oracle) memungkinkan Anda mengunci pernyataan PREPARE ke rencana eksekusi tertentu tanpa mengubah SQL aplikasi Anda. Ketika pengoptimal memilih rencana suboptimal setelah pembaruan statistik, peningkatan versi, atau perubahan parameter binding, gunakan Outline untuk mengunci rencana yang telah terbukti baik dan mencegah regresi.
Outline merupakan bagian dari SQL plan management (SPM). Fitur ini hanya mendukung rencana eksekusi tetap; rencana eksekusi yang berevolusi tidak didukung.
Prasyarat
Sebelum memulai, pastikan Anda telah mengajukan permohonan daftar putih polar_outline di Quota Center. Di kolom Actions, klik Apply di samping polardb_pg_polar_outline.
Siapkan ekstensi
Buat ekstensi
polar_outline:CREATE EXTENSION polar_outline;Semua fungsi dan relasi Outline disimpan dalam skema
polar_outline.Tambahkan skema tersebut ke jalur pencarian agar Anda dapat memanggil fungsi Outline tanpa awalan skema:
SET search_path TO "$user", public, polar_outline;Aktifkan penerapan rencana tetap:
SET polar_outline.use_stored_plan TO ON;
Siapkan data uji
Jalankan pernyataan berikut untuk membuat tabel bernama t dan memasukkan data ke dalamnya:
CREATE TABLE t(a INT, b INT);
INSERT INTO t SELECT i, i FROM generate_series(1, 1000) i;Perbarui data dalam tabel untuk memastikan pengoptimal menggunakan statistik yang akurat:
ANALYZE t;Jalankan pernyataan PREPARE:
PREPARE test AS SELECT * FROM t WHERE a=$1;Data uji ini hanya berlaku untuk contoh pada bagian ini. Sesuaikan pernyataan berdasarkan kebutuhan bisnis Anda.
Fitur Outline menyediakan petunjuk untuk mengontrol rencana eksekusi yang akan ditangkap. Jika Anda menggunakan petunjuk tersebut dalam suatu pernyataan, rencana eksekusi pernyataan itu akan ditangkap. Selanjutnya, jika Anda menjalankan pernyataan tersebut tanpa petunjuk, pernyataan tersebut tetap dieksekusi berdasarkan rencana eksekusi yang telah ditangkap.
Tangkap dan kunci rencana eksekusi
Fitur Outline hanya dapat mengunci rencana eksekusi untuk pernyataan PREPARE.
Pilih metode penangkapan berdasarkan situasi Anda:
| Situasi | Metode |
|---|---|
| Kunci rencana untuk satu pernyataan | Panggil polar_outline_create secara langsung (disarankan) |
| Tangkap rencana untuk beberapa pernyataan sekaligus | Gunakan flag capture_plan |
Metode 1: Panggil polar_outline_create (disarankan)
polar_outline_create menangkap dan mengunci rencana untuk satu panggilan EXECUTE dalam satu langkah.
SELECT polar_outline_create('EXECUTE test(100)');Output yang diharapkan:
polar_outline_create
----------------------
t
(1 row)Metode 2: Gunakan flag capture_plan
Gunakan metode ini ketika Anda perlu menangkap rencana untuk beberapa pernyataan dalam satu sesi.
Metode ini menghasilkan cache rencana.
Aktifkan penangkapan rencana:
SET polar_outline.capture_plan TO ON;Jalankan setiap pernyataan yang rencananya ingin Anda kunci:
EXECUTE test(100);Setelah semua rencana ditangkap, nonaktifkan penangkapan rencana:
SET polar_outline.capture_plan TO OFF;
Tulis ulang kueri menggunakan pergantian rencana
Jika terjadi masalah performa setelah PolarDB melakukan penulisan ulang kueri SQL, Anda dapat menggunakan fitur Outline untuk menulis ulang kueri SQL tersebut.
Kedua rencana eksekusi harus setara secara semantis. Pergantian rencana yang tidak setara dapat menghasilkan set hasil yang salah.
Contoh berikut mengganti rencana untuk SQL1 (yang menggunakan Hash Join) dengan rencana yang lebih efisien dari SQL2 (yang menggunakan Nested Loop dengan lateral join).
SQL1 — kueri asli:
select t.a, t2.avg_b
from t join (select avg(b) as avg_b, a
from t2
group by a) t2
on t2.a = t.a and t.c < $1
order by t.a;SQL2 — kueri yang ditulis ulang dengan semantik setara:
select t.a, t2.avg_b
from t join lateral (select avg(b) as avg_b
from t2
where t2.a = t.a) as t2
on t.c < $1
order by t.a;Siapkan tabel uji:
CREATE TABLE t(a int, b int, c int); INSERT INTO t SELECT i % 100000, i, i FROM generate_series(1, 1000000) i; CREATE TABLE t2 AS SELECT * FROM t; CREATE INDEX ON t(c); CREATE INDEX ON t2(a); ANALYZE t, t2;Tangkap rencana untuk kedua kueri:
PREPARE s1 AS SELECT t.a, t2.avg_b FROM t JOIN (SELECT avg(b) AS avg_b, a FROM t2 GROUP BY a) t2 ON t2.a = t.a AND t.c < $1 ORDER BY t.a; PREPARE s2 AS SELECT t.a, t2.avg_b FROM t JOIN LATERAL (SELECT avg(b) AS avg_b FROM t2 WHERE t2.a = t.a) AS t2 ON t.c < $1 ORDER BY t.a; SELECT polar_outline.polar_outline_create('EXECUTE s1(5)'); SELECT polar_outline.polar_outline_create('EXECUTE s2(5)');Kedua panggilan mengembalikan
tjika berhasil.Ganti rencana untuk
s1agar menggunakan rencana daris2. Parameter input adalah ID dari kedua rencana eksekusi dalam outline:SELECT polar_outline.polar_outline_switch(1, 2);Konfirmasi dengan
EXPLAINbahwas1kini menggunakan rencana Nested Loop:EXPLAIN (COSTS FALSE) EXECUTE s1(5);Output yang diharapkan setelah pergantian:
QUERY PLAN ------------------------------------------------------- Sort Sort Key: t.a -> Nested Loop -> Index Scan using t_c_idx on t Index Cond: (c < $1) -> Aggregate -> Bitmap Heap Scan on t2 Recheck Cond: (a = t.a) -> Bitmap Index Scan on t2_a_idx Index Cond: (a = t.a) (10 rows)Hapus outline untuk
s2, yang sudah tidak diperlukan lagi:SELECT polar_outline.polar_outline_delete(2);
Parameter
Semua parameter berada dalam namespace polar_outline. Atur parameter tersebut dengan SET polar_outline.<parameter> TO <value>;.
| Parameter | Nilai | Deskripsi |
|---|---|---|
use_stored_plan | ON, OFF | Mengontrol apakah rencana yang dikunci diberlakukan. Atur ke ON untuk menggunakan rencana yang tersimpan; atur ke OFF agar pengoptimal bebas memilih. |
capture_plan | ON, OFF | Mengontrol apakah fitur Outline menangkap rencana secara otomatis saat pernyataan dijalankan. Menghasilkan cache rencana saat diaktifkan. |
log_usage | none, debug, debug1–debug5, log, info, notice, warning | Mengatur tingkat detail output log Outline. none menonaktifkan logging. debug–debug5 memberikan detail yang semakin lengkap untuk troubleshooting. log, info, notice, dan warning dipetakan ke level keparahan log PostgreSQL yang sesuai. |
Catatan penggunaan
Fitur Outline hanya dapat mengunci rencana untuk pernyataan PREPARE. Kueri ad-hoc tidak didukung.
Petunjuk yang disematkan dalam suatu pernyataan akan menangkap rencana untuk eksekusi tersebut. Eksekusi berikutnya dari pernyataan yang sama tanpa petunjuk tetap menggunakan rencana yang telah ditangkap.
Data uji yang digunakan dalam contoh hanya untuk ilustrasi. Sesuaikan definisi tabel dan nilai parameter agar sesuai dengan workload Anda.