PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Berapa masa hidup pernyataan yang disiapkan sisi server PostgreSQL

Jadi, pertanyaan Anda akhirnya bermuara pada "bagaimana java.sql.PreparedStatement bermain dengan PostgreSQL". Lihat jawaban tentang "bagaimana ini dimainkan dengan paket yang disiapkan server" di bagian akhir.

Inilah jawabannya:itu tergantung pada driver JDBC yang Anda gunakan.

TL;DR :dalam driver modern, pernyataan yang disiapkan server akan tetap hidup hingga koneksi mati atau hingga pernyataan digusur oleh pernyataan lain (pengusiran LRU biasa).

Catatan:Server PostgreSQL tidak dapat membagikan pernyataan yang telah disiapkan di seluruh koneksi database, sehingga driver JDBC terbaik yang dapat dilakukan adalah menyimpan rencana dalam cache di setiap koneksi.

Catatan:Spesifikasi JDBC mengamanatkan penggunaan ?, ? untuk mengikat placeholder, sementara server menginginkan $1, $2 jadi driver JDBC juga menyimpan apa yang disebut teks SQL yang diurai.

Ada dua driver JDBC yang terkenal:pgjdbc dan pgjdbc-ng

pgjdbc

https://github.com/pgjdbc/pgjdbc

Sejak pgjdbc 9.4-1202 itu secara otomatis menyimpan paket sisi server saat menggunakan PreparedStatement .Catatan:pernyataan di-cache bahkan jika Anda close() PreparedStatement .Untuk mendapatkan persiapan sisi server, Anda perlu menjalankan kueri 5 kali (yang dapat dikonfigurasi melalui prepareThreshold ).

Saat ini, cache diimplementasikan per koneksi. Secara default pgjdbc menyimpan 256 (preparedStatementCacheQueries ) kueri dan hingga preparedStatementCacheSizeMiB dari pertanyaan. Ini adalah pengaturan konservatif, jadi Anda mungkin ingin menyesuaikannya. Lihat dokumentasi untuk deskripsi properti. Cache mencakup pernyataan yang diurai dan disiapkan server.

masalah github:https://github.com/pgjdbc/pgjdbc/pull/319

pgjdbc-ng

https://github.com/impossibl/pgjdbc-ng

Saya tidak menyukai pgjdbc-ng, namun sepertinya keduanya melakukan parsing (ukuran cache default adalah 250 kueri) dan persiapan server (ukuran cache default adalah 50 pertanyaan). Dukungan pernyataan yang disiapkan sisi server diluncurkan pada 24 Feb 2014, jadi jika Anda menggunakan versi yang agak baru, Anda bisa mendapatkan cache pernyataan.

Catatan:jika Anda secara tidak sengaja menggunakan kueri yang sangat panjang, Anda dapat menekan OutOfMemory karena pgjdbc-ng tidak dapat menghapus entri berdasarkan jumlah byte yang disimpan.

Cache adalah per-koneksi, sehingga digunakan secara transparan bahkan jika Anda menutup pernyataan.

Saya tidak bisa mengatakan banyak tentang kinerja pgjdbc-ng meskipun sejak terakhir kali saya mencoba untuk melemparkan jmh itu gagal dengan pengecualian acak.

masalah github:https://github.com/impossibl/pgjdbc-ng/pull/ 69

Paket yang disiapkan server

PostgreSQL memiliki PREPARE dan DEALLOCATE perintah untuk mereferensikan pernyataan saat mengirim EXEC di atas kawat. Ini mengoptimalkan dua hal:

  1. Saat menggunakan PREPARE d (dengan kata lain, yang disiapkan server), klien tidak perlu mengirim teks kueri berulang kali. Itu hanya mengirimkan nama kueri pendek dan nilai untuk variabel pengikat.
  2. Sejak 9.2, database masih mencoba untuk merencanakan ulang beberapa eksekusi kueri pertama. Itu dilakukan untuk mencoba jika kueri membutuhkan banyak paket atau jika paket generik cukup baik. Akhirnya (segera jika kueri tidak memiliki parameter), database mungkin beralih ke paket umum .
  3. Sejak 12, ada pengaturan untuk memaksa SEMUA pernyataan yang disiapkan server dieksekusi dengan paket umum atau khusus:plan_cache_mode =auto | force_custom_plan | force_generic_plan

Dengan kata lain, PreparedStatement mengoptimalkan penguraian kueri di sisi JDBC dan perencanaan kueri di sisi basis data.

Info lebih lanjut di sini:http://blog.endpoint .com/2014/04/custom-plans-prepared-statements-in.html

Pernyataan yang disiapkan dalam PL/pgSQL

Sesuai dokumentasi, PostgreSQL cache rencana untuk kueri yang digunakan dalam PL/pgSQL. Ini terjadi setelah beberapa eksekusi (3 atau 5, saya tidak ingat ambang batas yang tepat), jadi setelah Anda membuat prosedur tersimpan mungkin agak lambat, namun kemudian akan beralih ke paket yang di-cache (asalkan database setuju untuk menggunakan paket generik untuk kueri tertentu).

Dengan kata lain untuk mencapai "rencana eksekusi yang di-cache", Anda perlu menggunakan driver JDBC terbaru, atau Anda dapat membungkus semua kueri Anda ke dalam prosedur tersimpan. Panggilan ke prosedur akan direncanakan ulang pada setiap eksekusi, namun panggilan itu sendiri biasanya jauh lebih pendek daripada kueri yang menyusun prosedur.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Memanggil transform() tanpa set SRID tidak didukung

  2. Mengonversi hubungan banyak-ke-banyak menjadi satu-ke-banyak di PostgreSQL

  3. Postgresql:Membuat skrip eksekusi psql dengan kata sandi

  4. * Bidang tidak dikenal di:database Maksud Anda?:- metrik - server - logging - DROPWIZARD

  5. Sinkronkan data postgreSql dengan ElasticSearch