Ich habe eine einfache Tabelle in Postgres mit etwas mehr als 8 Millionen Zeilen. Die Spalte von Interesse enthält kurze Textzeichenfolgen, typischerweise eine oder mehrere Wörter mit einer Gesamtlänge von weniger als 100 Zeichen. Es wird als "Charaktervariation (100)" festgelegt. Die Spalte ist indiziert. Ein einfaches Nachschlagen wie unten zeigt & gt; 3000 ms.
%Vor%Ja, jetzt müssen Sie einfach die Zeilen finden, in denen "a" mit dem eingegebenen Text beginnt. Ich möchte die Geschwindigkeit des Nachschlagens auf unter 100 ms bringen (das Auftreten von Momentanwerten). Vorschläge? Es scheint mir, dass die Volltextsuche hier nicht helfen wird, da meine Textspalte zu kurz ist, aber ich würde es gerne versuchen, wenn es sich lohnt.
Ach ja, ich habe auch genau die gleichen Daten in mongodb und die indizierte Spalte "a" geladen. Das Laden der Daten in mongodb war erstaunlich schnell (mongodb ++). Sowohl mongodb als auch Postgres sind ziemlich genau, wenn sie exakte Lookups machen. Aber, Postgres glänzt wirklich, wenn das Nachziehen der Wildcard-Suchen wie oben gemacht wird und konsistent ungefähr 1/3 so lang wie mongodb nimmt. Ich wäre glücklich, mongodb zu verfolgen, wenn ich das beschleunigen könnte, da dies nur eine readonly Operation ist.
Update: Zuerst einige EXPLAIN ANALYZE
Ausgaben
Ich möchte tatsächlich Lower(a)
mit dem Suchbegriff vergleichen, der immer mindestens 4 Zeichen lang ist, also
Also habe ich einen Index erstellt
%Vor%Scheint das einzige Mal, wenn ein Index verwendet wird, wenn ich nach einer genauen Übereinstimmung suche
%Vor% Finden Sie eine Lösung, indem Sie einen Index mit varchar_pattern_ops
und implementieren bin jetzt auf der Suche nach einem noch schnelleren Nachschlagen .
Der PostgreSQL-Abfrageplaner ist intelligent, aber keine KI. Verwenden Sie für die Verwendung eines Index für einen Ausdruck die exakt dieselbe Ausdrucksform in der Abfrage.
Mit einem Index wie diesem:
%Vor%Oder einfacher in PostgreSQL 9.1:
%Vor%Verwenden Sie diese Abfrage:
%Vor%Was ist 100% funktional äquivalent zu:
%Vor%Oder:
%Vor%Aber nicht :
%Vor%Dies ist eine funktional andere Abfrage und Sie benötigen einen anderen Index:
%Vor%Oder einfacher mit PostgreSQL 9.1:
%Vor%Und benutze diese Abfrage:
%Vor%Groß- und Kleinschreibung nicht beachten. Index:
Bearbeiten : Fast vergessen: Wenn Sie Ihre Datenbank mit einem anderen Gebietsschema als dem Standard-C ausführen, müssen Sie spezielle Angabe der Operatorklasse - text_pattern_ops
in meinem Beispiel:
Abfrage:
%Vor%Kann den Index verwenden und ist fast so schnell wie die Variante mit fester Länge.
Vielleicht interessiert Sie dieser Beitrag auf dba.SE mit weiteren Details zum Mustervergleich , insbesondere dem letzten Teil über die Operatoren ~>=~
und ~<~
.
Es ist eindeutig dokumentiert, dass eine Suche mit regulärem Ausdruck keine Indizes für eine Vielzahl von Implementierungen verwendet. Die einzige Möglichkeit, Indizes mit regulären Ausdrücken zu verwenden, ist auf eine Präfix-Suche wie ein * beschränkt.
Tags und Links postgresql mongodb