Question

je demanderai à la mauvaise question dans le titre. Voici les faits:

Mes gens de service à la clientèle se plaignent de temps de réponse lent lorsque vous faites des recherches des clients sur l'interface d'administration de notre site basé sur Django.

Nous utilisons Postgres 8.4.6. J'ai commencé à vous connecter requêtes lentes et découvert ce coupable:

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

Cette requête prend plus de 32 secondes pour courir. Voici le plan de requête 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)

Parce que c'est une requête générée par le Django ORM d'un Django QuerySet généré par l'application Django Admin, je n'ai aucun contrôle sur la requête elle-même. Un indice semble comme la solution logique. J'ai essayé de créer un index pour accélérer ce, mais il n'a pas fait une différence:

CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))

Qu'est-ce que je fais mal? Comment puis-je accélérer cette requête?

Était-ce utile?

La solution

Il n'y a pas de support d'index pour LIKE / ILIKE PostgreSQL 8.4 - à l'exception gauche recherche anchored termes .

Depuis PostgreSQL 9.1 le module supplémentaire pg_trgm fournit des classes d'opérateurs pour GIN et GiST indices trigrammes de soutien LIKE / ILIKE ou des expressions régulières (opérateurs ~ et amis). Installer une fois par base de données:

CREATE EXTENSION pg_trgm;

Exemple index GIN:

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

Related:

Autres conseils

Cet indice ne va pas aider à cause de la « % » au début de votre match - un indice de BTREE ne peut préfixes correspondre et le caractère générique au début de vos moyens de requête il n'y a pas de préfixe fixes à rechercher.

Voilà pourquoi il est en train de faire une analyse de table et correspondant à chaque enregistrement à son tour contre la chaîne de requête.

Vous avez probablement besoin de regarder à l'aide d'un index de texte intégral et les opérateurs de correspondance de texte plutôt que de faire la recherche de sous-chaîne avec LIKE que vous êtes en ce moment. Vous pouvez trouver plus sur la recherche en texte intégral dans la documentation:

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

En fait je remarque de cette page que, comme utilise apparemment jamais index, ce qui me semble étrange comme il devrait être en mesure de résoudre les préfixes non génériques en utilisant un indice de BTREE. Quelques tests rapides suggère que la documentation est probablement correcte mais, dans ce cas, aucun montant d'indexation va aider pendant que vous utilisez LIKE pour résoudre la requête.

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top