Jika Anda ingin mengoptimalkan kecocokan substring arbitrer, salah satu opsi adalah menggunakan pg_tgrm
modul
. Tambahkan indeks:
CREATE INDEX table_location_name_trigrams_key ON table
USING gin (location_name gin_trgm_ops);
Ini akan memecah "Simple Cafe" menjadi "sim", "imp", "mpl", dll., dan menambahkan entri ke indeks untuk setiap trigam di setiap baris. Perencana kueri kemudian dapat secara otomatis menggunakan indeks ini untuk pencocokan pola substring, termasuk:
SELECT * FROM table WHERE location_name ILIKE '%cafe%';
Kueri ini akan mencari "caf" dan "afe" di indeks, menemukan persimpangan, mengambil baris tersebut, lalu memeriksa setiap baris dengan pola Anda. (Pemeriksaan terakhir itu diperlukan karena persimpangan "caf" dan "afe" cocok dengan "simple cafe" dan "unsafe scaffolding", sedangkan "%cafe%" hanya cocok dengan satu). Indeks menjadi lebih efektif karena pola input menjadi lebih panjang karena dapat mengecualikan lebih banyak baris, tetapi masih tidak seefisien pengindeksan seluruh kata, jadi jangan berharap peningkatan kinerja di atas to_tsvector
.
Menariknya, trigram tidak berfungsi sama sekali untuk pola yang di bawah tiga karakter. Itu mungkin atau mungkin bukan pemecah kesepakatan untuk aplikasi Anda.
Sunting: Saya awalnya menambahkan ini sebagai komentar.
Aku punya pikiran lain tadi malam ketika aku kebanyakan tidur. Buat cjk_chars
fungsi yang mengambil string input, regexp_matches
seluruh rentang CJK Unicode, dan mengembalikan larik karakter tersebut atau NULL
jika tidak ada. Tambahkan indeks GIN di cjk_chars(location_name)
. Kemudian kueri untuk:
WHERE CASE
WHEN cjk_chars('query') IS NOT NULL THEN
cjk_chars(location_name) @> cjk_chars('query')
AND location_name LIKE '%query%'
ELSE
<tsvector/trigrams>
END
Ta-da, unigram!