Saya mungkin mengajukan pertanyaan yang salah dalam judul. Berikut ini faktanya:
Masyarakat layanan pelanggan saya mengeluh tentang waktu respons yang lambat ketika melakukan pencarian pelanggan pada antarmuka administrasi situs berbasis Django kami.
Kami menggunakan Postgres 8.4.6. Saya mulai mencatat pertanyaan yang lambat, dan menemukan penyebabnya:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
Kueri ini membutuhkan waktu hingga 32 detik untuk dijalankan. Inilah paket kueri yang disediakan oleh EXPLAIN:
QUERY PLAN
Aggregate (cost=205171.71..205171.72 rows=1 width=0)
-> Seq Scan on auth_user (cost=0.00..205166.46 rows=2096 width=0)
Filter: (upper((email)::text) ~~ '%DEYK%'::text)
Karena ini adalah kueri yang dihasilkan oleh Django ORM dari Django QuerySet yang dihasilkan oleh aplikasi Admin Django, saya tidak memiliki kontrol atas kueri itu sendiri. Indeks sepertinya solusi logis. Saya mencoba membuat indeks untuk mempercepat ini, tetapi tidak ada bedanya:
CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))
Apa yang saya lakukan salah? Bagaimana saya bisa mempercepat permintaan ini?
Indeks itu tidak akan membantu karena '%' di awal pertandingan Anda - indeks BTREE hanya dapat mencocokkan awalan dan wildcard di awal kueri Anda berarti tidak ada awalan tetap yang harus dicari.
Itu sebabnya ia melakukan pemindaian tabel dan mencocokkan setiap catatan pada gilirannya dengan string kueri.
Anda mungkin perlu melihat menggunakan indeks teks lengkap dan operator pencocokan teks daripada melakukan pencarian substring dengan SEPERTI bahwa Anda saat ini. Anda dapat menemukan lebih banyak tentang pencarian teks lengkap dalam dokumentasi:
http://www.postgresql.org/docs/8.4/static/textsearch-intro.html
Bahkan saya perhatikan dari halaman itu bahwa LIKE sepertinya tidak pernah menggunakan indeks, yang menurut saya aneh karena seharusnya bisa menyelesaikan awalan non-wildcard menggunakan indeks BTREE. Namun, beberapa tes cepat menunjukkan bahwa dokumentasi mungkin benar, dalam hal ini tidak ada jumlah pengindeksan yang akan membantu saat Anda menggunakan LIKE untuk menyelesaikan kueri.
sumber
%
adalah fitur yang diperlukan: perwakilan layanan pelanggan membutuhkannya untuk menemukan akun pelanggan, terutama ketika ada salah ketik di alamat email.