Mengidentifikasi komponen pemrosesan kueri
Ada empat tahap terpisah untuk menjalankan kueri. Dalam urutan eksekusi tahapan ini adalah:
- Penguraian
- Transformasi (Penulisan Ulang)
- Perencanaan
- Eksekusi
Pengurai
Pengurai bertanggung jawab untuk memeriksa string kueri untuk sintaks yang valid. Pengurai memiliki dua bagian utama:
- gram.y yang terdiri dari sekumpulan aturan tata bahasa dan tindakan yang sesuai.
- scan.1lexer, yang mengenali pengidentifikasi dan kata kunci SQL. Setiap kata kunci atau identifikator memicu pembuatan token yang kemudian diberikan kepada pengurai.
Pengurai menyusun pohon kueri, yang memisahkan kueri menjadi bagian yang dapat diidentifikasi untuk memahami tabel mana yang terlibat, filter apa yang diterapkan, dll. Bagian pohon kueri adalah:
- Jenis perintah - SELECT, INSERT, UPDATE, atau DELETE.
-
Entri tabel rentang (RTE) - daftar relasi,
ietabel, subkueri, hasil gabungan, dll. Dalam pernyataan SELECT, item ini muncul setelah kata kunci FROM. - Hubungan hasil - hubungan hasil untuk perintah INSERT, UPDATE, dan DELETE, adalah tabel atau tampilan di mana perubahan akan diterapkan.
- Daftar target - hasil kueri, diidentifikasi antara kata kunci SELECT dan FROM. Perintah DELETE tidak menghasilkan hasil, sehingga perencana menambahkan entri khusus untuk memungkinkan pelaksana menemukan baris yang akan dihapus. Perintah INSERT mengidentifikasi baris baru yang harus masuk ke hubungan hasil. Untuk perintah UPDATE, daftar target menjelaskan baris baru yang harus menggantikan baris lama.
- Kualifikasi - nilai Boolean yang menentukan apakah operasi untuk baris hasil akhir harus dijalankan atau tidak. Ini sesuai dengan klausul WHERE dari pernyataan SQL.
- Pohon gabungan - pohon ini bisa menjadi daftar item FROM. Gabungan dapat dilakukan dalam urutan apa pun, atau dilakukan dalam urutan tertentu, seperti Gabungan luar.
- Lainnya - item yang tidak relevan pada tahap ini, seperti klausa ORDER BY.
Penulis Ulang
Output pengurai diteruskan ke transformasi atau proses penulisan ulang , kecuali kesalahan ditemukan dalam hal ini pesan kesalahan dikembalikan.
Penulis ulang kueri menulis ulang teks kueri dengan menerapkan aturan ke dalamnya. Penulis ulang mempertimbangkan aturan, lalu meneruskan kueri yang dimodifikasi ke perencana kueri. Keamanan tingkat baris diimplementasikan pada tahap ini.
Misalnya, aturan pada SELECT selalu diterapkan sebagai langkah terakhir, termasuk untuk kueri INSERT, UPDATE, dan DELETE. Aturan juga berarti bahwa kueri UPDATE tidak menimpa baris yang ada, sebaliknya baris baru disisipkan, dan baris lama disembunyikan. Setelah transaksi disahkan, proses pembersihan dapat menghapus baris tersembunyi.
Perencana
Tugas perencana adalah mengambil aturan pemrosesan kueri dan memahami cara mana yang paling cepat untuk eksekusi kueri.
Perencana membuat pohon rencana, dengan simpul yang mewakili operasi fisik pada data.
PostgreSQL menggunakan pengoptimal kueri berbasis biaya untuk menemukan rencana optimal untuk kueri. Perencana mengevaluasi berbagai rencana eksekusi dan memperkirakan berapa banyak sumber daya yang diperlukan, seperti siklus CPU, operasi I/O, dll. Perkiraan ini kemudian dikonversi menjadi unit, yang dikenal sebagai biaya paket. Paket dengan biaya terendah dipilih.
Namun, ketika jumlah gabungan meningkat, jumlah rencana yang mungkin tumbuh secara eksponensial. Mengevaluasi setiap rencana yang mungkin menjadi tidak mungkin bahkan untuk kueri yang relatif sederhana. Heuristik dan algoritma digunakan untuk membatasi jumlah rencana yang mungkin. Hasilnya adalah bahwa paket yang dipilih mungkin bukan rencana optimal. Namun, ini hampir optimal, dan dipilih dalam waktu yang wajar.
Biayanya adalah perkiraan terbaik perencana. Tujuan estimasi biaya adalah untuk membandingkan rencana eksekusi yang berbeda untuk kueri yang sama dalam kondisi yang sama . Perencana menggunakan statistik yang dikumpulkan pada tabel dan baris untuk menghasilkan perkiraan biaya untuk kueri. Agar perkiraan biaya akurat, statistik harus diperbarui.
Statistik terbaru
Komponen perencana pengoptimal kueri menggunakan statistik tentang tabel dan baris untuk menghasilkan perkiraan biaya yang akurat.
ANALYZE mengumpulkan statistik tentang tabel database dan menyimpan hasilnya dalam katalog sistem pg_statistic . Anda perlu menjalankan ANALYZE, jika:
- Anda menonaktifkan autovacuum (yang biasanya menganalisis tabel secara otomatis)
- Anda menonaktifkan autovacuum, dan belum menjalankan ANALYZE baru-baru ini
- Salah satu dari yang sebelumnya, dan ada banyak pernyataan INSERT, UPDATE, atau DELETE.
Perkiraan biaya bergantung pada statistik up-to-tanggal, dan jika statistik tersebut sudah kedaluarsa, maka rencana yang tidak efisien dapat dipilih. Ketika tidak ada parameter yang diteruskan ke ANALYZE, setiap tabel dalam database diperiksa.
Sintaks untuk ANALYZE adalah:
ANALYZE [ VERBOSE ] [ ***table*** [ ( ***column*** [, ...] ) ] ]
VERBOSE menampilkan pesan kemajuan untuk menunjukkan tabel mana yang sedang dianalisis, bersama dengan beberapa statistik.
Jadwalkan VACUUM dan ANALYZE untuk dijalankan setiap hari pada saat waktu penggunaan rendah. ANALYZE dapat berjalan secara paralel dengan aktivitas lain karena hanya memerlukan kunci baca pada tabel target.
Eksekutor
Fase ini mengambil rencana yang dibuat oleh perencana dan memprosesnya secara rekursif untuk mengekstrak kumpulan baris yang diperlukan. Setiap kali simpul rencana dipanggil, pelaksana harus menyampaikan sebuah baris data, atau melaporkan kembali apakah sudah selesai.
Pelaksana mengevaluasi keempat jenis kueri SQL:
- PILIH
- Masukkan
- Pembaruan
- MENGHAPUS
Untuk SELECT, pelaksana mengembalikan setiap baris kembali ke klien sebagai kumpulan hasil.
Untuk INSERT, setiap baris yang dikembalikan disisipkan ke dalam tabel yang ditentukan. Tugas ini dilakukan dalam simpul rencana tingkat atas khusus yang disebut ModifyTable.
Untuk UPDATE, setiap baris komputasi menyertakan semua nilai kolom yang diperbarui, ditambah ID baris dari baris target. Data dikirim ke simpul ModifikasiTabel, yang membuat baris yang diperbarui dan menandai baris lama sebagai dihapus.
Untuk DELETE, satu-satunya kolom yang dikembalikan oleh rencana adalah ID baris. Simpul ModifikasiTabel menggunakan ID baris untuk menandai baris sebagai dihapus.