FTS tidak mendukung LIKE
The jawaban yang diterima sebelumnya tidak benar. Pencarian Teks Lengkap dengan indeks teks lengkapnya sama sekali bukan untuk LIKE
operator, ia memiliki operator sendiri dan tidak berfungsi untuk string arbitrer. Ini beroperasi pada kata-kata berdasarkan kamus dan stemming. Ini tidak mendukung awalan yang cocok untuk kata-kata , tetapi tidak dengan LIKE
Operator:
Indeks trigram untuk LIKE
Instal modul tambahan pg_trgm
yang menyediakan kelas operator untuk indeks trigram GIN dan GiST untuk mendukung semua LIKE
dan ILIKE
pola , bukan hanya yang berlabuh kiri:
Contoh indeks:
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Atau:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
Contoh kueri:
SELECT * FROM tbl WHERE col LIKE '%foo%'; -- leading wildcard
SELECT * FROM tbl WHERE col ILIKE '%foo%'; -- works case insensitively as well
Trigram? Bagaimana dengan string yang lebih pendek?
Kata-kata dengan kurang dari 3 huruf dalam nilai yang diindeks masih berfungsi. Manualnya:
Setiap kata dianggap memiliki dua spasi diawali dan satu spasi saat menentukan himpunan trigram yang terdapat dalam string.
Dan pola pencarian dengan kurang dari 3 huruf? Manualnya:
Baik untuk LIKE
pencarian ekspresi reguler maupun regular, perlu diingat bahwa pola tanpa trigram yang dapat diekstrak akan merosot menjadi scan indeks penuh.
Artinya, pemindaian indeks indeks / bitmap masih berfungsi (rencana kueri untuk pernyataan yang disiapkan tidak akan rusak), itu tidak akan memberi Anda kinerja yang lebih baik. Biasanya tidak ada kerugian besar, karena string 1 atau 2 huruf hampir tidak selektif (lebih dari beberapa persen kecocokan tabel yang mendasarinya) dan dukungan indeks tidak akan meningkatkan kinerja untuk memulai, karena pemindaian tabel lengkap lebih cepat.
text_pattern_ops
untuk pencocokan awalan
Untuk pola jangkar kiri saja (tanpa wildcard terkemuka) Anda mendapatkan yang optimal dengan kelas operator yang sesuai untuk indeks btree: text_pattern_ops
atau varchar_pattern_ops
. Kedua fitur bawaan Postgres standar, tidak diperlukan modul tambahan. Performa serupa, tetapi indeks jauh lebih kecil.
Contoh indeks:
CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
Contoh kueri:
SELECT * FROM tbl WHERE col LIKE 'foo%'; -- no leading wildcard
Atau , jika Anda harus menjalankan database Anda dengan lokal 'C' (secara efektif tidak ada lokal), maka semuanya akan disortir menurut urutan byte dan indeks btree biasa dengan kelas operator default melakukan tugasnya.
Lebih detail, penjelasan, contoh dan tautan dalam jawaban terkait ini di dba.SE:
pg_trgm
Anda memerlukan string kueri yang panjangnya minimal 3 karakter, misalnyafo%
tidak akan mengenai indeks tetapi melakukan pemindaian sebagai gantinya. Sesuatu untuk diperhatikan.Mungkin yang cepat adalah pola berlabuh dengan case-sensitive seperti itu dapat menggunakan indeks. yaitu tidak ada kartu bebas di awal string pertandingan sehingga pelaksana dapat menggunakan pemindaian rentang indeks. ( komentar relevan di dokumen ada di sini ) Lower dan ilike juga akan kehilangan kemampuan Anda untuk menggunakan indeks kecuali Anda secara khusus membuat indeks untuk tujuan itu (lihat indeks fungsional ).
Jika Anda ingin mencari string di tengah bidang, Anda harus melihat ke dalam indeks teks lengkap atau trigram . Yang pertama ada di inti Postgres, yang lainnya tersedia di modul kontrib.
sumber
Anda dapat menginstal Wildspeed , jenis indeks yang berbeda di PostgreSQL. Wildspeed berfungsi dengan% word% wildcard, tidak masalah. Sisi negatifnya adalah ukuran indeks, ini bisa besar, sangat besar.
sumber
Silakan Jalankan kueri yang disebutkan di bawah ini untuk meningkatkan kinerja kueri LIKE di postgresql. buat indeks seperti ini untuk tabel yang lebih besar:
sumber
untuk apa nilainya, Django ORM cenderung menggunakan
UPPER(text)
untuk semuaLIKE
permintaan untuk membuatnya tidak peka huruf besar / kecil,Menambahkan indeks
UPPER(column::text)
telah sangat mempercepat sistem saya, tidak seperti hal lainnya.Sejauh memimpin%, ya itu tidak akan menggunakan indeks. Lihat blog ini untuk penjelasan yang bagus:
https://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning
sumber
Saya baru-baru ini mengalami masalah serupa dengan tabel yang berisi 200000 catatan dan saya perlu melakukan kueri LIKE berulang kali. Dalam kasus saya, string yang sedang dicari sudah diperbaiki. Bidang lainnya bervariasi. Karena itu, saya bisa menulis ulang:
sebagai
Saya senang ketika kueri kembali dengan cepat dan memverifikasi bahwa indeks digunakan dengan
EXPLAIN ANALYZE
:sumber
Kueri suka Anda mungkin tidak dapat menggunakan indeks yang Anda buat karena:
1) kriteria LIKE Anda dimulai dengan wildcard.
2) Anda telah menggunakan fungsi dengan kriteria LIKE Anda.
sumber
Kapanpun Anda menggunakan klausa pada kolom dengan fungsi seperti LIKE, ILIKE, upper, lower dll. Kemudian postgres tidak akan mempertimbangkan indeks normal Anda. Ini akan melakukan pemindaian penuh dari tabel melalui setiap baris dan oleh karena itu akan lambat.
Cara yang benar adalah dengan membuat indeks baru sesuai dengan kueri Anda. Misalnya jika saya ingin mencocokkan kolom tanpa sensitivitas huruf dan kolom saya adalah varchar. Kemudian Anda bisa melakukannya seperti ini.
Demikian pula jika kolom Anda adalah teks maka Anda melakukan sesuatu seperti ini
Demikian pula Anda dapat mengubah fungsi atas ke fungsi lain yang Anda inginkan.
sumber