Mogę zadawać złe pytanie w tytule. Oto fakty:
Pracownicy działu obsługi klienta narzekają na długi czas reakcji podczas wyszukiwania klientów w interfejsie administracyjnym naszej witryny opartej na Django.
Używamy Postgres 8.4.6. Zacząłem rejestrować powolne zapytania i odkryłem tego winowajcę:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
Uruchomienie tego zapytania zajmuje ponad 32 sekundy. Oto plan zapytań dostarczony przez 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)
Ponieważ jest to zapytanie wygenerowane przez Django ORM z zestawu Django QuerySet wygenerowanego przez aplikację administracyjną Django, nie mam żadnej kontroli nad samym zapytaniem. Indeks wydaje się logicznym rozwiązaniem. Próbowałem utworzyć indeks, aby to przyspieszyć, ale to nie miało znaczenia:
CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))
Co ja robię źle? Jak mogę przyspieszyć to zapytanie?