Saya tidak dapat berbicara tentang antarmuka Perl sisi klien itu sendiri tetapi saya dapat menjelaskan tentang sisi server PostgreSQL.
PostgreSQL telah menyiapkan pernyataan dan pernyataan tidak siap. Pernyataan tidak siap diurai, direncanakan dan dieksekusi segera. Mereka juga tidak mendukung substitusi parameter. Pada psql
biasa shell Anda dapat menampilkan rencana kueri mereka seperti ini:
tmpdb> explain select * from sometable where flag = true;
Di sisi lain ada pernyataan yang disiapkan:Mereka biasanya (lihat "pengecualian" di bawah) diuraikan dan direncanakan dalam satu langkah dan dieksekusi pada langkah kedua. Mereka dapat dieksekusi ulang beberapa kali dengan parameter yang berbeda, karena mereka melakukannya mendukung substitusi parameter. Setara dalam psql
apakah ini:
tmpdb> prepare foo as select * from sometable where flag = $1;
tmpdb> explain execute foo(true);
Anda mungkin melihat, bahwa rencana tersebut berbeda dengan rencana dalam pernyataan tidak siap, karena perencanaan sudah dilakukan di prepare
fase seperti yang dijelaskan dalam dokumen untuk SIAPKAN
:
Ini juga berarti, bahwa rencananya TIDAK dioptimalkan untuk parameter yang diganti:Pada contoh pertama mungkin menggunakan indeks untuk flag
karena PostgreSQL tahu bahwa dalam satu juta entri hanya sepuluh yang memiliki nilai true
. Alasan ini tidak mungkin ketika PostgreSQL menggunakan pernyataan yang disiapkan. Dalam hal ini rencana dibuat yang akan bekerja untuk semua nilai parameter yang mungkin sebaik mungkin. Ini mungkin mengecualikan indeks yang disebutkan karena mengambil bagian yang lebih baik dari tabel lengkap melalui akses acak (karena indeks) lebih lambat daripada pemindaian sekuensial biasa. SIAPKAN
doc mengkonfirmasi ini:
BTW - Mengenai rencana caching, SIAPKAN doc juga memiliki sesuatu untuk dikatakan:
Juga tidak ada caching paket otomatis dan tidak ada caching/penggunaan kembali melalui beberapa koneksi.
PENGECUALIAN :Saya telah menyebutkan "biasanya". psql
yang ditampilkan contoh bukanlah hal yang benar-benar digunakan oleh adaptor klien seperti Perl DBI. Ini menggunakan protokol
tertentu . Di sini istilah "kueri sederhana" sesuai dengan "kueri yang tidak disiapkan" di psql
, istilah "perpanjangan kueri " sesuai dengan "permintaan yang disiapkan" dengan satu pengecualian:Ada perbedaan antara (satu) "pernyataan tanpa nama" dan (mungkin beberapa) "pernyataan bernama". Mengenai pernyataan bernama dok
mengatakan:
dan juga:
Jadi dalam hal ini perencanaan dilakukan tanpa parameter seperti yang dijelaskan diatas untuk PREPARE
- tidak ada yang baru.
Pengecualian yang disebutkan adalah "pernyataan tanpa nama". Kata dokter:
Dan inilah manfaatnya:Meskipun pernyataan tanpa nama "disiapkan" (yaitu dapat memiliki substitusi parameter), itu juga dapat menyesuaikan rencana kueri dengan parameter aktual.
BTW:Penanganan yang tepat dari pernyataan tanpa nama telah berubah beberapa kali dalam rilis server PostgreSQL sebelumnya. Anda dapat mencari dokumen lama untuk detailnya jika Anda benar-benar menginginkannya.
Alasan - Perl / klien mana pun :
Bagaimana seorang klien seperti Perl menggunakan protokol adalah pertanyaan yang sama sekali berbeda. Beberapa klien seperti driver JDBC untuk Java pada dasarnya mengatakan:Bahkan jika programmer menggunakan pernyataan yang disiapkan, lima (atau lebih) eksekusi pertama secara internal dipetakan ke "permintaan sederhana" (yaitu secara efektif tidak siap), setelah itu driver beralih ke " pernyataan bernama".
Jadi klien memiliki pilihan berikut:
- Paksakan (ulang)perencanaan setiap kali menggunakan protokol "kueri sederhana".
- Rencanakan sekali, jalankan beberapa kali dengan menggunakan protokol "perpanjangan kueri" dan "pernyataan bernama" (rencana mungkin buruk karena perencanaan dilakukan tanpa parameter).
- Mengurai sekali, rencanakan untuk setiap eksekusi (dengan versi PostgreSQL saat ini) dengan menggunakan protokol "extended query" dan "pernyataan tanpa nama" dan patuhi beberapa hal lagi (berikan beberapa parameter selama pesan "parse")
- Mainkan trik yang sama sekali berbeda seperti driver JDBC.
Apa yang Perl lakukan saat ini:Saya tidak tahu. Tetapi "ikan haring merah" yang disebutkan tidak terlalu tidak mungkin.