Domanda

I può essere chiedendo la domanda sbagliata nel titolo. Ecco i fatti:

I miei popolare servizio clienti si sono lamentati tempi di risposta lenti quando facendo ricerche sul cliente l'interfaccia di amministrazione del nostro sito Django-based.

Stiamo usando Postgres 8.4.6. Ho iniziato la registrazione query lente, e scoperto questo colpevole:

SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')

Questa query sta prendendo verso l'alto di 32 secondi per l'esecuzione. Ecco il piano di query fornita da SPIEGARE:

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 dal Django ORM da un QuerySet Django generato dall'applicazione Django Admin, non ho alcun controllo su query stessa. Un indice sembra la soluzione logica. Ho cercato di creare un indice per accelerare questo, ma non ha fatto la 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 ricerca?

È stato utile?

Soluzione

Non v'è alcun supporto indice per LIKE / ILIKE in PostgreSQL 8.4 - fatta eccezione per rimasto ancorato ricerca termini .

Da PostgreSQL 9.1 il modulo aggiuntivo pg_trgm fornisce classi di operatori per gli indici gIN e GiST trigram sostegno LIKE / ILIKE o espressioni regolari (operatori ~ e amici). Installare una volta per database:

CREATE EXTENSION pg_trgm;

Esempio indice GIN:

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

Related:

Altri suggerimenti

Questo indice non sta andando per aiutare a causa della '%' all'inizio del match - un indice BTREE può corrispondere solo prefissi e il carattere jolly all'inizio del vostro mezzo di query non c'è è fissata prefisso da cercare.

è per questo che sta facendo una scansione di tabella e la congruenza ogni record, a sua volta contro la stringa di query.

È probabilmente bisogno di guardare con un indice completo e gli operatori di corrispondenza del testo, piuttosto che fare la ricerca sottostringa con LIKE che siete in questo momento. È possibile trovare maggiori sulla ricerca testo completo nella documentazione:

http://www.postgresql.org/docs/8.4/static/textsearch-intro .html

In realtà ho preavviso da quella pagina che, come a quanto pare non utilizza gli indici, che sembra strano per me come dovrebbe essere in grado di risolvere i prefissi non jolly utilizzando un indice BTREE. Alcuni test rapidi suggerisce che la documentazione è probabilmente corretto però, in tal caso, nessuna quantità di indicizzazione è essere di aiuto mentre si sta utilizzando LIKE per risolvere la query.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top