Varian yang TIDAK DAPAT DIUBAH dari unaccent()
Untuk memperjelas informasi yang salah dalam jawaban salah yang diterima saat ini
:
Indeks ekspresi hanya mengizinkan IMMUTABLE
fungsi (untuk alasan yang jelas) dan unaccent()
hanya STABLE
. solusi yang Anda sarankan di komentar juga bermasalah. Penjelasan mendetail dan solusi yang tepat untuk itu :
Tergantung pada konten tags->name
mungkin berguna untuk menambahkan unaccent()
ke indeks ekspresi, tapi itu ortogonal dengan pertanyaan mengapa indeks tidak digunakan:
Masalah/solusi aktual
Operator LIKE
dalam kueri Anda secara halus salah (yang paling disukai). Anda tidak ingin menafsirkan 'Weststrasse' sebagai pola pencarian, Anda ingin mencocokkan string (dinormalisasi) apa adanya. Ganti dengan =
operator, dan Anda akan melihat pemindaian indeks (bitmap) dengan indeks Anda saat ini, terlepas volatilitas fungsi unaccent()
:
SELECT * FROM germany.ways
WHERE lower(tags->'name') = lower(unaccent('unaccent','Weststrasse'))
Mengapa?
Operan kanan LIKE
adalah pola . Postgres tidak dapat menggunakan indeks btree biasa untuk pencocokan pola ( pengecualian berlaku
). LIKE
dengan string biasa sebagai pola (tidak ada karakter khusus) dapat dioptimalkan dengan pemeriksaan kesetaraan pada indeks btree. Tetapi jika ada karakter khusus dalam string, ini indeks keluar.
Jika ada IMMUTABLE
fungsi di sebelah kanan LIKE
, dapat segera dievaluasi dan optimasi tersebut masih dimungkinkan. Per dokumentasi tentang Kategori Volatilitas Fungsi
:
Hal yang sama tidak mungkin dilakukan dengan volatilitas fungsi yang lebih rendah (STABLE
atau VOLATILE
). Itulah mengapa "solusi" Anda memalsukan IMMUTABLE unaccent()
sepertinya berhasil, tapi itu benar-benar memberi lipstik pada babi.
Untuk mengulangi:
- Jika Anda ingin bekerja dengan
LIKE
dan pola, gunakan indeks trigram . - Jika Anda tidak ingin bekerja dengan
LIKE
dan pola, gunakan operator persamaan=