Frage

Ich kann die falsche Frage im Titel stellen. Hier sind die Fakten:

Meine Kundendienstleute haben sich über langsame Reaktionszeiten beschwert, wenn sie Kundensuche auf der Verwaltungsschnittstelle unserer Django-basierten Website durchführen.

Wir verwenden Postgres 8.4.6. Ich fing an, langsame Abfragen zu protokollieren und entdeckte diesen Schuldigen:

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

Diese Abfrage dauert 32 Sekunden, um zu laufen. Hier ist der Abfrageplan von Erklärung:

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)

Da es sich um eine Abfrage handelt, die vom Django Orm aus einem Django -Queryset generiert wurde, das von der Django -Administratoranwendung generiert wird, habe ich keine Kontrolle über die Abfrage selbst. Ein Index scheint die logische Lösung zu sein. Ich habe versucht, einen Index zu erstellen, um dies zu beschleunigen, aber er hat keinen Unterschied gemacht:

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

Was mache ich falsch? Wie kann ich diese Abfrage beschleunigen?

War es hilfreich?

Lösung

Es gibt keine Indexunterstützung für LIKE / ILIKE in PostgreSQL 8.4 - ausser für links verankerte Suchbegriffe.

Seit PostgreSQL 9.1 das zusätzliche Modul pg_trgm Bietet Bedienungsklassen für Gin- und Gist -Trigrammindizes unterstützend LIKE / ILIKE oder reguläre Ausdrücke (Operatoren ~ und Freunde). Installieren Sie einmal pro Datenbank:

CREATE EXTENSION pg_trgm;

Beispiel Gin Index:

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

Verwandt:

Andere Tipps

Dieser Index wird aufgrund des '%' zu Beginn Ihres Spiels nicht helfen - ein BTREE -Index kann nur Präfixe übereinstimmen, und die Wildcard zu Beginn Ihrer Abfrage bedeutet, dass kein festes Präfix zu suchen ist.

Deshalb wird ein Tischscan durchgeführt und jeder Datensatz wiederum mit der Abfragezeichenfolge übereinstimmt.

Sie müssen sich wahrscheinlich ansehen, wenn Sie einen Volltextindex und den Text übereinstimmen, anstatt die Substring -Suche mit so zu erledigen, dass Sie sich im Moment befinden. In der Dokumentation finden Sie mehr über die Suche nach Volltext:

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

Tatsächlich merke ich von dieser Seite, die anscheinend niemals Indizes verwendet, was mir seltsam erscheint, da sie in der Lage sein sollte, Präfixe von Nicht-Wildkarten mit einem BTREE-Index aufzulösen. Einige schnelle Tests deuten darauf hin, dass die Dokumentation wahrscheinlich korrekt ist. In diesem Fall hilft keine Indexierung, während Sie die Abfrage gerne beheben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top