I may be asking the wrong question in the title. Here are the facts:
My customer service folk have been complaining about slow response times when doing customer lookups on the administration interface of our Django-based site.
We're using Postgres 8.4.6. I started logging slow queries, and discovered this culprit:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
This query is taking upwards of 32 seconds to run. Here's the query plan provided by 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)
Because this is a query generated by the Django ORM from a Django QuerySet generated by the Django Admin application, I don't have any control over the query itself. An index seems like the logical solution. I tried creating an index to speed this up, but it hasn't made a difference:
CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))
What am I doing wrong? How can I speed up this query?
%is a necessary feature: the customer service reps need it for finding customer accounts, especially when there's a typo in the email address. – David Eyk Aug 09 '11 at 23:17LIKEcannot use a default btree index at all - if you are not using the standardClocale (most people don't). But the claim thatLIKE apparently never uses indexesis just wrong. It can use an index for left-anchored search terms just like you suggested at first. The locale may come in your way. Either use theClocale or an appropriate operator class for the index. Details in this related answer. – Erwin Brandstetter Jul 28 '12 at 18:53