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
LIKEdan pola, gunakan indeks trigram . - Jika Anda tidak ingin bekerja dengan
LIKEdan pola, gunakan operator persamaan=