Ich stelle möglicherweise die falsche Frage im Titel. Hier sind die Fakten:
Mein Kundenservice hat sich über langsame Antwortzeiten beschwert, als er auf der Administrationsoberfläche unserer Django-basierten Site nach Kunden gesucht hat.
Wir verwenden Postgres 8.4.6. Ich begann langsame Abfragen zu protokollieren und entdeckte diesen Täter:
SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')
Die Ausführung dieser Abfrage dauert mindestens 32 Sekunden. Hier ist der von EXPLAIN bereitgestellte Abfrageplan:
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 dies eine Abfrage ist, die vom Django ORM aus einem Django QuerySet generiert wurde, das von der Django Admin-Anwendung generiert wurde, kann ich die Abfrage selbst nicht steuern. Ein Index scheint die logische Lösung zu sein. Ich habe versucht, einen Index zu erstellen, um dies zu beschleunigen, aber es 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?
Dieser Index ist nicht hilfreich, da zu Beginn Ihres Abgleichs ein '%' angezeigt wird. Ein BTREE-Index kann nur Präfixe abgleichen, und der Platzhalter am Anfang Ihrer Abfrage bedeutet, dass kein festes Präfix gesucht werden muss.
Aus diesem Grund wird ein Tabellenscan durchgeführt, bei dem alle Datensätze der Reihe nach mit der Abfragezeichenfolge abgeglichen werden.
Wahrscheinlich müssen Sie einen Volltextindex und die Textvergleichsoperatoren verwenden, anstatt die Teilstringsuche mit LIKE durchzuführen, wie Sie es gerade tun. Weitere Informationen zur Volltextsuche finden Sie in der Dokumentation:
http://www.postgresql.org/docs/8.4/static/textsearch-intro.html
Tatsächlich stelle ich auf dieser Seite fest, dass LIKE anscheinend niemals Indizes verwendet, was mir seltsam erscheint, da es in der Lage sein sollte, Nicht-Platzhalter-Präfixe mithilfe eines BTREE-Index aufzulösen. Ein paar schnelle Tests deuten jedoch darauf hin, dass die Dokumentation wahrscheinlich korrekt ist. In diesem Fall hilft kein Indizierungsaufwand, während Sie LIKE zum Auflösen der Abfrage verwenden.
quelle
%
Merkmal ist auch ein notwendiges Merkmal: Die Kundendienstmitarbeiter benötigen es zum Auffinden von Kundenkonten, insbesondere wenn die E-Mail-Adresse einen Tippfehler enthält.