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

unaccent() mencegah penggunaan indeks di Postgres

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 =



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kueri dalam kueri:Apakah ada cara yang lebih baik?

  2. Tidak dapat menginstal permata pg di Mountain Lion

  3. Mendapatkan daftar tabel yang bergantung pada tampilan/tabel di PostgreSQL

  4. Bagaimana Lantai() Bekerja di PostgreSQL

  5. Buat kolom tipe presisi ganda[] dengan liquibase