Potrei fare la domanda sbagliata nel titolo. Ecco i fatti:
Le persone del mio servizio clienti si sono lamentate dei tempi di risposta lenti durante le ricerche dei clienti sull'interfaccia di amministrazione del nostro sito basato su Django.
Stiamo usando Postgres 8.4.6. Ho iniziato a registrare query lente e ho scoperto questo colpevole:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
L'esecuzione di questa query richiede 32 secondi. Ecco il piano di query fornito da 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)
Poiché si tratta di una query generata da Django ORM da un Django QuerySet generato dall'applicazione Django Admin, non ho alcun controllo sulla query stessa. Un indice sembra la soluzione logica. Ho provato a creare un indice per accelerarlo, ma non ha fatto differenza:
CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))
Che cosa sto facendo di sbagliato? Come posso velocizzare questa query?