Warum würden Sie text_pattern_ops für eine Textspalte indizieren?

18

Heute haben mich sieben Datenbanken in sieben Wochen mit den Operatorenindizes vertraut gemacht.

Sie können Zeichenfolgen für die Musterübereinstimmung mit den vorherigen Abfragen text_pattern_opsindizieren, indem Sie einen Operatorklassenindex erstellen , sofern die Werte in Kleinbuchstaben indiziert sind.

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);

Wir haben die verwendet, text_pattern_opsweil der Titel vom Typ Text ist. Wenn Sie zum Index Varchars, Zeichen oder Namen, verwenden Sie die entsprechenden ops: varchar_pattern_ops, bpchar_pattern_ops, und name_pattern_ops.

Ich finde das Beispiel wirklich verwirrend. Warum ist das sinnvoll?

Wenn die Spalte vom Typ Text ist, werden die anderen Typen (varchar, char, name) nicht in Text umgewandelt, bevor sie als Suchwert verwendet werden?

Wie verhält sich dieser Index anders als mit dem Standardoperator?

CREATE INDEX moves_title_pattern ON movies (lower(title));
Iain Samuel McLean Elder
quelle
1
Diese verwandte Frage kann hilfreich sein: dba.stackexchange.com/questions/10694/…
Erwin Brandstetter
Danke, Erwin. Ihre Antwort auf diese Frage war sehr hilfreich bei der Recherche nach den Ideen im Buch.
Iain Samuel McLean Elder

Antworten:

20

Die Dokumentation gibt Ihnen häufig eine Antwort auf solche Fragen. Wie auch in diesem Fall :

Die Operatorklassen text_pattern_ops, varchar_pattern_ops und bpchar_pattern_ops unterstützen B-Tree-Indizes für die Typen text, varchar und char. Der Unterschied zu den Standardoperatorklassen besteht darin, dass die Werte strikt zeichenweise verglichen werden und nicht gemäß den länderspezifischen Kollatierungsregeln. Dadurch sind diese Operator-Klassen für Abfragen mit Mustervergleichsausdrücken (reguläre LIKE- oder POSIX-Ausdrücke) geeignet, wenn die Datenbank nicht das Standard-Gebietsschema "C" verwendet. Als Beispiel könnten Sie eine varchar-Spalte wie folgt indizieren:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

Beachten Sie, dass Sie auch einen Index mit der Standardoperatorklasse erstellen sollten, wenn Abfragen mit normalen <, <=,> oder> = Vergleichen einen Index verwenden sollen. Solche Abfragen können die Operatorklassen xxx_pattern_ops nicht verwenden . (Normale Gleichheitsvergleiche können diese Operatorklassen jedoch verwenden.) Es ist möglich, mehrere Indizes für dieselbe Spalte mit verschiedenen Operatorklassen zu erstellen.

In der Dokumentation heißt es weiter:

Wenn Sie das Gebietsschema C verwenden, benötigen Sie die Operatorklassen xxx_pattern_ops nicht, da ein Index mit der Standardoperatorklasse für Mustervergleichsabfragen im Gebietsschema C verwendet werden kann.

Sie können Ihr Gebietsschema wie folgt überprüfen (es ist wahrscheinlich UTF8 anstelle von "C"):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8
dezso
quelle
Aha! Ich habe das gelesen, aber es fiel mir schwer, dem zu folgen, also habe ich es nicht aufgenommen. Würden Sie sagen, dass der nützliche Nutzen von text_pattern_opsvom Gebietsschema abhängt? Es scheint mir von Vorteil zu sein, da mein Gebietsschema 'en_US.UTF-8' (nicht 'C') ist, sodass Musterabfragen nicht den Standardindex verwenden können.
Iain Samuel McLean Elder
Genau. Ich würde hinzufügen (aber dies ist nur eine Spekulation), dass die Standardoperatorklasse bei Daten, die innerhalb der grundlegenden ASCII-Zeichen bleiben, genauso gut ist - zumindest sehe ich Abfragen mit LIKE 'something%', die solche Indizes verwenden.
Dezso
5
@dezso: Wenn Sie eine LIKEAbfrage mit einem einfachen B-Tree-Index gesehen haben, muss die Datenbank das CGebietsschema verwenden. Oder der Index wird mit COLLATE "POSIX"(oder COLLATE "C") definiert und die Abfrage gibt eine Übereinstimmung an COLLATION. Bei anderen Sortierungen stimmt die Reihenfolge des Index nicht mit den Gebietsschemaregeln überein und kann daher nicht für den Mustervergleich verwendet werden.
Erwin Brandstetter
1
@ErwinBrandstetter Ich muss bestätigen, du hast recht.
Dezso
1
@StopHarmingMonica Sie erhalten die richtige Antwort (und keinen Fehler), nur die Abfrage wird möglicherweise langsamer, nicht in der Lage, den Index zu verwenden.
11.