Topik ini menjelaskan cara PolarDB for MySQL menggunakan transformasi kueri berbasis biaya (CBQT) untuk meningkatkan efisiensi eksekusi kueri kompleks.
Prasyarat
Versi lama transformasi kueri:
Kluster adalah PolarDB for MySQL 8.0.2 dengan revisi versi 8.0.2.2.0 atau lebih baru.
Versi baru transformasi kueri:
Kluster adalah PolarDB for MySQL 8.0.2 dengan revisi versi 8.0.2.2.19 atau lebih baru.
Untuk informasi tentang cara memeriksa versi kluster Anda, lihat Kueri Versi Mesin.
Informasi latar belakang
Transformasi kueri mengacu pada proses mengubah pernyataan kueri menjadi pernyataan lain yang setara. Contoh pernyataan kueri berikut:
SELECT *
FROM d1
JOIN f1 ON d1.c1 = f1.c1
LEFT JOIN (
SELECT d2.c2 AS d2_c2, f2.c3 AS f2_c3
FROM d2, f2
WHERE d2.c1 = f2.c1
) derived
ON derived.d2_c2 = d1.c2
AND derived.f2_c3 = f1.c3;Pernyataan tersebut dapat diubah menjadi pernyataan kueri berikut berdasarkan aturan penggabungan tabel materialisasi:
SELECT *
FROM d1
JOIN f1 ON d1.c1 = f1.c1
LEFT JOIN (d2
JOIN f2 ON TRUE)
ON d2.c1 = f2.c1
AND f2.c3 = f1.c3
AND d2.c2 = d1.c2;Edisi Komunitas MySQL hanya mendukung transformasi kueri berbasis aturan, selama itu transformasi semantik dilakukan. Contoh sebelumnya adalah transformasi kueri khas oleh Edisi Komunitas MySQL. Namun, transformasi seperti itu tidak memberikan optimasi kinerja dalam beberapa kasus. Sebagai contoh, jika indeks dari d1, f1 dan d2, f2 tidak berkorelasi, setiap baris dalam hasil operasi join untuk d1 dan f1 memerlukan operasi join individual untuk d2 dan f2. Akibatnya, efisiensi eksekusi sangat berkurang. Oleh karena itu, transformasi kueri, terutama transformasi kompleks, harus dilakukan berdasarkan biaya eksekusi. Faktor-faktor seperti kardinalitas, metode akses, dan urutan join dapat memengaruhi biaya eksekusi. PolarDB for MySQL mendukung transformasi kueri berbasis biaya yang dapat melakukan jenis transformasi tertentu berdasarkan biaya eksekusi.
Untuk kueri kompleks, CBQT menggabungkan semua metode transformasi yang mungkin ke dalam kumpulan yang disebut ruang status. Kemudian, CBQT memilih rencana eksekusi dengan biaya terendah untuk kueri tersebut. Gambar berikut menggambarkan proses transformasi kueri berbasis biaya. CBQT mengumpulkan metode transformasi A dan B dan menghasilkan kombinasi berikut dalam ruang status: None (tanpa transformasi), A (hanya transformasi A), B (hanya transformasi B), dan AB (kedua transformasi A dan B). Kombinasi dalam ruang status masing-masing sesuai dengan rencana eksekusi. CBQT kemudian memilih rencana eksekusi dengan biaya terendah. Dalam contoh ini, Plan 2 dipilih, yang sesuai dengan transformasi A. Selain itu, transformasi yang dapat menghemat biaya eksekusi didefinisikan sebagai transformasi kueri berbasis aturan. Transformasi tersebut dilakukan jika aturan transformasi kueri terpenuhi.
Ambil pernyataan kueri sebelumnya sebagai contoh. Rencana eksekusi setelah penggabungan tabel materialisasi ditunjukkan pada gambar berikut:
Rencana eksekusi sebelum penggabungan tabel materialisasi ditunjukkan pada gambar berikut:
Rencana mana yang optimal tergantung pada apakah indeks dari d2, f2 dan d1, f1 berkorelasi, serta ukuran set hasil join. Jika indeks berkorelasi, rencana eksekusi setelah penggabungan adalah yang optimal. Sebaliknya, rencana eksekusi sebelum penggabungan adalah yang optimal. Kerangka kerja CBQT menghitung dan membandingkan biaya rencana eksekusi sebelum dan sesudah penggabungan tabel. Rencana yang optimal dalam skenario saat ini dipilih.
Istilah
Kueri Bersarang dan Kedalaman Bersarang
Kueri bersarang adalah blok kueri yang bersarang di dalam kueri lain. Blok kueri tersebut adalah subkueri atau kueri internal, sedangkan kueri eksternal adalah kueri induk atau kueri luar. Kedalaman bersarang adalah jumlah lapisan bersarang dari sebuah kueri, dan terutama digunakan untuk menggambarkan subkueri dan tabel materialisasi. Contoh:
SELECT * FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2 WHERE t2.c=t1.b);Kedalaman bersarang adalah 2. Kueri induk adalah pernyataan kueri yang menanyakan tabel t1, dan subkueri adalah pernyataan kueri yang menanyakan tabel t2.
Pernyataan UNION hanya menggabungkan pernyataan SQL pada lapisan yang sama. Contoh:
SELECT *
FROM t1
WHERE t1.a IN (
SELECT dt.b
FROM (
SELECT b, c
FROM t2
UNION
SELECT b, c
FROM t3
) dt
WHERE dt.c = t1.b
);Kedalaman bersarang dari pernyataan kueri sebelumnya adalah 3. Subkueri dalam tabel dt adalah gabungan pernyataan SQL pada lapisan yang sama dengan menggunakan pernyataan UNION.
Transformasi
Proses mengubah kueri ke bentuk lain berdasarkan aturan kesetaraan, seperti penggabungan tabel materialisasi yang dijelaskan dalam bagian Informasi Latar Belakang.
Objek Transformasi
Objek yang berlaku untuk aturan kesetaraan, seperti tabel turunan dari penggabungan tabel materialisasi dalam bagian Informasi Latar Belakang. Aturan transformasi yang berbeda berlaku untuk objek transformasi yang berbeda. Misalnya, objek transformasi dari penggabungan tabel materialisasi adalah tabel materialisasi. Objek transformasi dari transformasi dari subkueri ke pernyataan SEMI JOIN adalah subkueri.
Iterasi
Jumlah kali transformasi dilakukan. CBQT mencoba melakukan semua transformasi yang mungkin pada semua objek. Setelah transformasi dilakukan, mungkin ada beberapa blok kueri yang dapat ditransformasi lagi. Misalnya, setelah subkueri ditransformasi menjadi tabel materialisasi, tabel tersebut dapat ditransformasi dengan menggunakan aturan penggabungan tabel materialisasi. Oleh karena itu, perlu dilakukan transformasi pada objek baru. Proses ini dikenal sebagai iterasi CBQT. Jumlah iterasi adalah jumlah kali proses transformasi dilakukan secara berulang.
Penggunaan
PolarDB for MySQL menyediakan dua versi CBQT. Konfigurasikan parameter cbqt_enabled untuk mengaktifkan atau menonaktifkan fitur ini. Konfigurasikan parameter cbqt_version untuk menentukan versi CBQT. Saat cbqt_version diatur ke 1, versi lama digunakan. Saat cbqt_version diatur ke 2, versi baru digunakan.
Parameter | Tingkat | Deskripsi |
cbqt_enabled | Global dan sesi | Mengaktifkan atau menonaktifkan CBQT. Nilai default adalah ON. Nilai valid:
|
cbqt_version | Global dan sesi | Menentukan versi CBQT. Nilai valid:
|
Lihat deskripsi rinci berikut tentang parameter dari kedua versi.
Versi lama CBQT
CBQT mungkin membutuhkan waktu lama untuk memilih rencana eksekusi optimal. Untuk menghindari dampak pada kueri jangka pendek, Anda dapat menggunakan parameter cbqt_cost_threshold untuk menentukan ambang batas pemicu CBQT untuk kueri. CBQT hanya dipicu ketika biaya kueri melebihi nilai parameter ini. Untuk subkueri yang disediakan oleh PolarDB tetapi tidak oleh Edisi Komunitas MySQL, dekorrelasi dilakukan dengan menggunakan klausa GROUP BY berdasarkan CBQT. Untuk transformasi yang disediakan dalam Edisi Komunitas MySQL, Anda dapat menentukan apakah mereka dilakukan berdasarkan biaya. Fitur penggabungan turunan dikontrol oleh variabel derived_merge_cost_based dari parameter polar_optimizer_switch.
Parameter | Tingkat | Deskripsi |
cbqt_cost_threshold | Global dan sesi | Ambang batas pemicu CBQT untuk kueri. CBQT hanya dipicu ketika biaya kueri melebihi nilai parameter ini. Nilai valid: 0 hingga 18446744073709551615. Nilai default: 100000. |
cbqt_timeout | Global dan sesi | Batas waktu untuk CBQT. Jika waktu yang dibutuhkan untuk menemukan rencana eksekusi optimal lebih lama daripada periode waktu yang ditentukan, CBQT berhenti mencari rencana optimal, dan menggunakan rencana terbaik yang telah ditemukan untuk mengeksekusi kueri. Nilai valid: 0 hingga 18446744073709551615. Nilai default: 200. Satuan: milidetik. Catatan Jika Anda mengatur nilainya ke 0, tidak ada batas waktu yang ditentukan. |
polar_optimizer_switch | Global dan sesi | Menentukan apakah akan mengaktifkan fitur optimasi kueri PolarDB. Nilai valid:
|
Versi baru CBQT
CBQT mungkin membutuhkan waktu lama untuk melakukan iterasi dan memilih rencana eksekusi optimal. Anda dapat mengonfigurasi parameter berikut untuk mengontrol proses tersebut.
Parameter | Tingkat | Deskripsi |
cbqt_iteration_limit | Global | Jumlah iterasi CBQT. Semakin banyak iterasi menunjukkan kemungkinan lebih tinggi untuk memilih rencana optimal dan lebih banyak waktu yang dikonsumsi. Semakin sedikit iterasi menunjukkan kemungkinan lebih rendah untuk memilih rencana optimal dan lebih sedikit waktu yang dikonsumsi. Nilai valid: 1 hingga 10. Nilai default: 1. |
cbqt_max_nested_level | Global dan sesi | Kedalaman bersarang maksimum dari pernyataan kueri yang dapat diproses oleh CBQT. Jika kedalaman bersarang dari pernyataan kueri melebihi nilai ini, CBQT tidak diimplementasikan untuk pernyataan kueri tersebut. Nilai valid: 1 hingga 64. Nilai default: 5. |
cbqt_search_strategy | Global | Strategi untuk CBQT memilih rencana optimal. Nilai valid:
|
cbqt_rule_switch | Global dan sesi | Menentukan apakah akan mengaktifkan fitur optimasi kueri dan apakah transformasi kueri dilakukan. Nilai valid:
|