PolarDB for PostgreSQL (Compatible with Oracle) dan mendukung Elastic Parallel Query untuk kueri analitik, menyediakan kemampuan pemrosesan transaksional dan analitik hibrida (HTAP). Topik ini menjelaskan cara menggunakan Elastic Parallel Query untuk meningkatkan performa kueri analitik.
Cara kerja
Saat suatu kueri menggunakan Elastic Parallel Query, node query coordinator (QC) membagi rencana eksekusi menjadi beberapa shard dan mengarahkannya ke node parallel execution (PX). Setiap node PX menjalankan bagian rencana yang ditugaskan dan mengembalikan hasil parsial ke node QC, yang kemudian menggabungkannya menjadi hasil akhir. Node QC adalah node yang menerima permintaan kueri awal.
Pada diagram tersebut, RO1 adalah node QC. Node ini menerima kueri, membagi rencana eksekusi, lalu mengarahkan shard rencana tersebut ke tiga node PX: RO2, RO3, dan RO4. Setiap node PX mengeksekusi shard rencananya, membaca blok data yang diperlukan dari penyimpanan bersama PolarFS, lalu mengembalikan hasilnya ke node QC. Node QC menggabungkan hasil tersebut dan mengembalikan output akhir.
Catatan penggunaan
Karena mengonsumsi sumber daya yang signifikan, fitur ini hanya cocok untuk kueri analitik yang tidak sering dijalankan.
Kontrol detail halus
- Tingkat sistem: Gunakan parameter untuk mengontrol apakah Elastic Parallel Query diaktifkan untuk semua kueri di semua sesi.
- Tingkat sesi: Gunakan
ALTER SESSIONatau parameter GUC tingkat sesi untuk mengontrol fitur ini pada sesi saat ini. - Tingkat kueri: Gunakan petunjuk (hint) untuk menentukan apakah kueri tertentu dijalankan secara paralel.
Parameter
Secara default, Elastic Parallel Query dinonaktifkan di PolarDB for PostgreSQL (Compatible with Oracle) dan . Untuk menggunakan fitur ini, konfigurasikan parameter berikut:
| Parameter | Deskripsi |
| polar_cluster_map | Mencantumkan nama semua node read-only di kluster PolarDB for PostgreSQL (Compatible with Oracle) dan Anda. Parameter ini diperbarui secara otomatis saat Anda menambahkan node read-only baru. Catatan Parameter ini hanya tersedia untuk kluster yang dibuat dengan versi kernel minor 1.1.20 (dirilis Januari 2022) atau lebih lama. |
| polar_px_nodes | Menentukan node read-only mana yang berpartisipasi dalam Elastic Parallel Query. Secara default, nilai ini kosong, artinya semua node read-only digunakan. Anda dapat menentukan node dalam daftar yang dipisahkan koma. Contohnya: |
| polar_px_enable_replay_wait | Di PolarDB for PostgreSQL (Compatible with Oracle) dan , bisa terjadi latensi replikasi antara node primary dan node read-only. Saat pernyataan DDL, seperti CREATE TABLE, dijalankan di node primary, node read-only harus memutar ulang log WAL yang sesuai sebelum tabel baru terlihat. Jika Anda mengatur polar_px_enable_replay_wait ke on, Elastic Parallel Query memberlakukan konsistensi kuat. Saat kueri paralel diarahkan ke node read-only, node tersebut harus memutar ulang log hingga entri terbaru yang dicatat sebelum kueri dimulai. Baru setelah itu kueri dieksekusi.Jika latensi replikasi tinggi, node read-only mungkin tidak melihat catatan DDL terbaru. Anda dapat mengatur Parameter ini dapat diaktifkan untuk peran database tertentu. |
| polar_px_max_workers_number | Mengatur jumlah maksimum proses worker PX untuk Elastic Parallel Query pada satu node. Nilai default-nya adalah 30. Jumlah total proses worker PX untuk semua sesi pada satu node tidak boleh melebihi nilai ini. |
| polar_enable_px | Menentukan apakah Elastic Parallel Query diaktifkan. Nilai default-nya adalah off. |
| polar_px_dop_per_node | Mengatur tingkat paralelisme (DoP) untuk sesi saat ini. Nilai default-nya adalah 1. Kami merekomendasikan mengatur nilai ini ke jumlah total core CPU. Jika Anda mengatur parameter ini ke N, sebuah sesi akan memulai N proses worker PX di setiap node yang berpartisipasi untuk menjalankan kueri. |
| px_workers | Menentukan apakah Elastic Parallel Query berlaku untuk tabel tertentu. Secara default, tidak berlaku. Fitur ini mengonsumsi sumber daya kluster yang signifikan, sehingga kami merekomendasikan Anda hanya mengaktifkannya untuk tabel tempat fitur ini secara eksplisit diatur. Contohnya:
|
| synchronous_commit | Menentukan apakah commit transaksi harus menunggu log WAL ditulis ke disk sebelum mengembalikan pesan sukses ke client. Nilai yang valid adalah:
Catatan Dalam mode PX, parameter ini harus diatur ke on. |
Contoh
Contoh ini menggunakan kueri sederhana pada satu tabel untuk menunjukkan cara menggunakan Elastic Parallel Query.
Latar belakang:
Jalankan perintah berikut untuk membuat tabel test dan memasukkan data sampel.
CREATE TABLE test(id int);
INSERT INTO test SELECT generate_series(1,1000000);
EXPLAIN SELECT * FROM test;
Secara default, Elastic Parallel Query dinonaktifkan. Rencana eksekusi untuk kueri tersebut menampilkan Seq Scan native:
QUERY PLAN
--------------------------------------------------------
Seq Scan on test (cost=0.00..35.50 rows=2550 width=4)
(1 row)
Ikuti langkah-langkah berikut untuk mengaktifkan dan menggunakan Elastic Parallel Query:
- Aktifkan Elastic Parallel Query untuk tabel
test.ALTER TABLE test SET (px_workers=1); SET polar_enable_px=on; EXPLAIN SELECT * FROM test;Hasilnya sebagai berikut:
QUERY PLAN ------------------------------------------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on test (scan partial) (cost=0.00..431.00 rows=1 width=4) Optimizer: PolarDB PX Optimizer (3 rows) - Kueri nama semua node read-only saat ini.
Jalankan perintah berikut:
SHOW polar_cluster_map;Hasilnya sebagai berikut:
polar_cluster_map ------------------- node1,node2,node3 (1 row)Hasil tersebut menunjukkan bahwa kluster memiliki tiga node read-only:
node1,node2, dannode3. - Tentukan bahwa hanya node read-only
node1dannode2yang berpartisipasi dalam Elastic Parallel Query.Jalankan perintah berikut:
SET polar_px_nodes='node1,node2';Kueri node yang berpartisipasi:
SHOW polar_px_nodes ;Hasilnya sebagai berikut:
polar_px_nodes ---------------- node1,node2 (1 row)
Data performa
Data performa berikut direkam di lingkungan pengujian dengan lima node read-only:
- Untuk pemindaian tabel penuh (
SELECT COUNT(*)), Elastic Parallel Query 60 kali lebih cepat daripada kueri paralel node tunggal. - Untuk beban kerja TPC-H, Elastic Parallel Query 30 kali lebih cepat daripada kueri paralel node tunggal.Catatan Dalam contoh ini, pengujian berdasarkan benchmark TPC-H dilakukan, tetapi tidak memenuhi semua persyaratan pengujian benchmark TPC-H. Oleh karena itu, hasil pengujian ini mungkin tidak dapat dibandingkan dengan hasil resmi benchmark TPC-H.
Menerapkan kontrol detail halus
Bagian ini menjelaskan cara menggunakan Elastic Parallel Query pada berbagai tingkat granularitas.
- Kontrol tingkat sistem
Anda dapat mengontrol Elastic Parallel Query di tingkat sistem dengan mengatur parameter GUC global untuk mengaktifkan fitur ini dan menentukan tingkat paralelisme (DoP).
Examplepostgres=# alter system set polar_enable_px=1; ALTER SYSTEM postgres=# alter system set polar_px_dop_per_node=1; ALTER SYSTEM postgres=# select pg_reload_conf(); pg_reload_conf ---------------- t (1 row) postgres=# \c postgres You are now connected to database "postgres" as user "postgres". postgres=# drop table if exists t1; DROP TABLE postgres=# select id into t1 from generate_series(1, 1000) as id order by id desc; SELECT 1000 postgres=# alter table t1 set (px_workers=1); ALTER TABLE postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) - Kontrol tingkat sesi
Anda dapat mengontrol Elastic Parallel Query untuk sesi saat ini dengan menggunakan sintaks ALTER SESSION atau dengan mengatur parameter GUC tingkat sesi.
- Sintaks ALTER SESSION
ALTER SESSION ENABLE PARALLEL QUERY ALTER SESSION DISABLE PARALLEL QUERY ALTER SESSION FORCE PARALLEL QUERY [PARALLEL integer]CatatanALTER SESSION ENABLE PARALLEL QUERYmemungkinkan sesi saat ini menggunakan hint atau sintaks paralel untuk mengaktifkan kueri paralel.ALTER SESSION DISABLE PARALLEL QUERYmemaksa sesi saat ini menggunakan eksekusi serial. Kueri paralel dinonaktifkan, dan semua hint atau sintaks paralel diabaikan.ALTER SESSION FORCE PARALLEL QUERY [PARALLEL integer]memaksa sesi saat ini menggunakan eksekusi paralel. Anda dapat secara opsional menentukan tingkat paralelisme (DoP) denganPARALLEL integer. Jika tidak ditentukan, sistem menggunakan DoP dari parameterpolar_px_dop_per_node.DoP akhir ditentukan berdasarkan urutan prioritas berikut: hint > klausa
FORCE PARALLEL> parameterpolar_px_dop_per_node.
Perintah ini hanya berlaku untuk sesi saat ini dan diatur ulang saat koneksi baru. Nilai default-nya adalah
enable.Example--enable postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = true; SET postgres=# alter session enable parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select /*+ PARALLEL(4)*/ * from t1 where id < 10; INFO: [HINTS] PX PARALLEL(4) accepted. QUERY PLAN ------------------------------------------- PX Coordinator 8:1 (slice1; segments: 8) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)--disable postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = true; SET postgres=# alter session disable parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select /*+ PARALLEL(4)*/ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows)--force postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = false; SET postgres=# alter session force parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# alter session force parallel query parallel 2; ALTER SESSION postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 4:1 (slice1; segments: 4) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) - Kontrol parameter GUC
Karena parameter GUC dapat diatur di tingkat sistem maupun sesi, Anda juga dapat menggunakannya untuk mengontrol perilaku pada sesi tertentu.
Examplepostgres=# set polar_enable_px = true; SET postgres=# set polar_px_dop_per_node = 1; SET postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
- Sintaks ALTER SESSION
- Kontrol tingkat kueri
Anda dapat menggunakan Petunjuk SQL (SQL hint) untuk mengontrol apakah kueri tertentu menggunakan Elastic Parallel Query dan mengatur tingkat paralelismenya (DoP). Sintaks hint-nya sebagai berikut:
/*+ PARALLEL(DEFAULT) */ /*+ PARALLEL(integer) */ /*+ NO_PARALLEL(tablename) */CatatanPARALLEL(DEFAULT)menentukan bahwa kueri menggunakan Elastic Parallel Query dengan tingkat paralelisme default yang ditentukan oleh parameter polar_px_dop_per_node.PARALLEL(integer)menentukan bahwa kueri menggunakan Elastic Parallel Query dengan tingkat paralelisme yang ditentukan.NO_PARALLEL(tablename)mencegah tabel yang ditentukan dikueri secara paralel. Jika kueri mencakup tabel ini, seluruh kueri dijalankan secara serial.- Untuk kompatibilitas dengan Oracle, aturan berikut berlaku saat Anda mencampur hint paralel:
- Untuk beberapa blok hint, seperti /*+ A */ /*+ B */ /*+ C */, hanya blok hint pertama yang berlaku.
- Jika beberapa hint paralel digunakan dalam satu blok hint, seperti /*+ parallel(A) parallel(B) */, dan nilai DoP-nya berbeda, hint tersebut bertentangan, sehingga semua hint paralel diabaikan. Jika nilainya sama, hint tersebut diterapkan.
- Jika hint
paralleldan hintno_paralleldigunakan dalam satu blok, seperti /*+ parallel(A) no_parallel(t1) */, hintno_paralleldiabaikan.
- Hanya hint
paralleldanno_parallelyang saat ini didukung untuk kueri paralel. - Untuk menggunakan hint dalam kontrol tingkat kueri, Anda harus mengatur parameter GUC polar_px_enable_hint ke true. Secara default, nilainya adalah false.
Examplepostgres=# set polar_enable_px = false; SET postgres=# set polar_px_dop_per_node = 1; SET postgres=# set polar_px_enable_hint = true; SET postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(DEFAULT) */ * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(4) */ * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 8:1 (slice1; segments: 8) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(0) */ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) postgres=# explain (verbose, costs off) select /*+ NO_PARALLEL(t1) */ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) - Efek gabungan dari berbagai tingkat
Saat pengaturan di berbagai tingkat digabungkan, perilaku akhir ditentukan oleh aturan berikut:
Tingkat sistem Tingkat sesi Tingkat kueri Hasil polar_enable_px=on polar_px_dop_per_node=X enable Tidak ada hint Paralel, DoP X polar_enable_px=on polar_px_dop_per_node=X enable PARALLEL(Y) Paralel, DoP Y polar_enable_px=on polar_px_dop_per_node=X enable NO_PARALLEL Serial polar_enable_px=on polar_px_dop_per_node=X disable Tidak ada hint Serial polar_enable_px=on polar_px_dop_per_node=X disable PARALLEL(Y) Serial polar_enable_px=on polar_px_dop_per_node=X disable NO_PARALLEL Serial polar_enable_px=on polar_px_dop_per_node=X FORCE PARALLEL Z Tidak ada hint Paralel, DoP Z polar_enable_px=on polar_px_dop_per_node=X FORCE PARALLEL Z PARALLEL(Y) Paralel, DoP Y polar_enable_px=on polar_px_dop_per_node=X FORCE PARALLEL Z NO_PARALLEL Serial polar_enable_px=off polar_px_dop_per_node=X enable Tidak ada hint Serial polar_enable_px=off polar_px_dop_per_node=X enable PARALLEL(Y) Paralel, DoP Y polar_enable_px=off polar_px_dop_per_node=X enable NO_PARALLEL Serial polar_enable_px=off polar_px_dop_per_node=X disable Tidak ada hint Serial polar_enable_px=off polar_px_dop_per_node=X disable PARALLEL(Y) Serial polar_enable_px=off polar_px_dop_per_node=X disable NO_PARALLEL Serial polar_enable_px=off polar_px_dop_per_node=X FORCE PARALLEL Z Tidak ada hint Paralel, DoP Z polar_enable_px=off polar_px_dop_per_node=X FORCE PARALLEL Z PARALLEL(Y) Paralel, DoP Y polar_enable_px=off polar_px_dop_per_node=X FORCE PARALLEL Z NO_PARALLEL Serial