Fungsi Postgres dideklarasikan dengan klasifikasi volatilitas VOLATILE
, STABLE
atauIMMUTABLE
. Proyek ini dikenal sangat ketat dengan label ini untuk fungsi bawaan. Dan dengan alasan yang bagus. Contoh yang menonjol: indeks ekspresi hanya memungkinkan IMMUTABLE
fungsi dan yang harus benar-benar berubah untuk menghindari hasil yang salah.
Fungsi yang ditentukan pengguna masih bebas untuk dinyatakan sesuai keinginan pemilik. Manual menyarankan:
Untuk hasil optimalisasi terbaik, Anda harus memberi label fungsi Anda dengan kategori volatilitas paling ketat yang berlaku untuknya.
... dan menambahkan daftar luas hal-hal yang dapat salah dengan label volatilitas yang salah.
Namun, ada beberapa kasus di mana memalsukan ketidakberdayaan masuk akal. Sebagian besar ketika Anda tahu fungsinya, pada kenyataannya, tidak berubah dalam lingkup Anda. Contoh:
Selain semua implikasi yang mungkin terjadi pada integritas data , apa efeknya terhadap kinerja? Orang mungkin berasumsi bahwa mendeklarasikan fungsi IMMUTABLE
hanya dapat bermanfaat bagi kinerja . Apakah begitu?
Bisakah mendeklarasikan volatilitas fungsi IMMUTABLE
merusak kinerja?
Mari kita asumsikan Postgres 10 saat ini untuk mempersempitnya, tetapi semua versi terbaru menarik.
sumber
FORCE
keduanya. 100% dari DBA PostgreSQL berpengalaman berbohong untuk mengerjakan UI itu dengan fungsi wrapper. Setidaknya denganFORCE
, kita tidak perlu pembungkus dan kita tidak perlu berbohong pada volatilitas yang diumumkan.FORCE
seharusnya membuat indeks ekspresi menerima fungsi yang tidak dapat diubah (sambil menandainya sebagai titik kegagalan potensial). Ya, itu akan tampak seperti solusi yang lebih elegan daripada pembungkus fungsi yang tidak berubah.Jawaban:
Ya, itu dapat merusak kinerja.
Fungsi SQL sederhana dapat "disejajarkan" dalam permintaan panggilan. Mengutip Postgres Wiki :
Penekanan berani saya.
Untuk menegakkan kebenaran, ada sejumlah prasyarat. Salah satunya :
Artinya, fungsi SQL menggunakan fungsi yang tidak dapat diubah tetapi masih dinyatakan
IMMTUTABLE
tidak termasuk dalam optimasi ini. Dipicu oleh jawaban terkait ini di SO, saya telah menjalankan tes ekstensif:Pada dasarnya membandingkan dua varian fungsi SQL sederhana ini (memetakan tanggal ke
integer
, mengabaikan tahun yang tidak penting untuk tujuan tersebut):Fungsi Postgres
to_char()
sajaSTABLE
, bukanIMMUTABLE
(semua contoh kelebihan - karena alasan di luar cakupan jawaban ini ). Jadi yang kedua palsuIMMUTABLE
dan ternyata 5x lebih lambat dalam tes sederhana:db <> biola di sini
Contoh spesifik ini dapat diganti dengan yang setara:
Akan tampak lebih mahal dengan dua panggilan fungsi dan lebih banyak perhitungan. Tapi
IMMUTABLE
label ini benar (ditambah, fungsi yang digunakan lebih cepat dan memaksatext
untukinteger
lebih mahal, juga).2x lebih cepat dari varian tercepat di atas (10x lebih cepat dari yang lebih lambat). Intinya adalah: Gunakan
IMMUTABLE
fungsi jika memungkinkan , maka Anda tidak perlu "menipu" untuk memulai.sumber
STABLE
juga sejajar. Saya pikir pengoptimal hanya akanIMMUTABLE
fungsi online .VOLATILE
juga.