Ich kann in der Dokumentation keine eindeutige Antwort auf diese Frage finden. Wenn eine Spalte ein Array-Typ ist, werden alle eingegebenen Werte einzeln indiziert?
Ich habe eine einfache Tabelle mit einer int[]
Spalte erstellt und einen eindeutigen Index darauf gesetzt. Mir ist aufgefallen, dass ich nicht dasselbe Ints-Array hinzufügen konnte, was mich zu der Annahme führt, dass der Index aus den Array-Elementen zusammengesetzt ist und nicht aus jedem Index.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
Hilft der Index bei dieser Abfrage?
arrays
postgresql
indexing
IamIC
quelle
quelle
jsonb
und die Indizes zu verwenden? postgresql.org/docs/9.5/static/functions-json.html und postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXINGAntworten:
Ja, Sie können ein Array indizieren, müssen jedoch die Array-Operatoren und den GIN-Indextyp verwenden .
Beispiel:
Ergebnis:
HinweisIn vielen Fällen scheint die Option gin__int_ops erforderlich zu sein
Ich habe noch keinen Fall gesehen, in dem es mit den Operatoren && und @> ohne die Optionen gin__int_ops funktionieren würde
quelle
gin__int_ops
sei denn, sie werden fürinteger[]
Spalten verwendet. Es dauerte Jahre der Frustration und der Suche nach anderen Lösungen, bis ich diese Op-Klasse entdeckte. Es ist ein Borderline-Wundertäter.@Tregoreg stellte im Kommentar zu seinem angebotenen Kopfgeld eine Frage :
@ Frank ist akzeptiert Antwort fordert Sie auf,Array-Operatoren zu verwenden, wasfür Postgres 11immernoch korrekt ist.Das Handbuch:
Die vollständige Liste der integrierten Operatorklassen für GIN-Indizes in der Standardverteilung finden Sie hier.
In Postgres sind Indizes an Operatoren gebunden (die für bestimmte Typen implementiert sind), nicht nur an Datentypen oder Funktionen oder irgendetwas anderes. Das ist ein Erbe des ursprünglichen Berkeley-Designs von Postgres und jetzt sehr schwer zu ändern. Und es funktioniert im Allgemeinen gut. Hier ist ein Thread zu pgsql-Bugs, in dem Tom Lane dies kommentiert.
Einige PostGis Funktionen (wie
ST_DWithin()
) scheinen gegen dieses zu verstoßen, aber das ist nicht so. Diese Funktionen werden intern neu geschrieben, um die jeweiligen Operatoren zu verwenden .Der indizierte Ausdruck muss sich links vom Operator befinden. Für die meisten Operatoren ( einschließlich aller oben genannten ) kann der Abfrageplaner dies erreichen, indem er Operanden umdreht, wenn Sie den indizierten Ausdruck rechts platzieren - vorausgesetzt, a
COMMUTATOR
wurde definiert. DasANY
Konstrukt kann in Kombination mit verschiedenen Operatoren verwendet werden und ist selbst kein Operator. Bei Verwendung alsconstant = ANY (array_expression)
nur Indizes, die den=
Operator für Array-Elemente unterstützen, würde sich qualifizieren und wir würden einen Kommutator für benötigen= ANY()
. GIN-Indizes sind out.Postgres ist derzeit nicht intelligent genug, um daraus einen GIN-indizierbaren Ausdruck abzuleiten. Für den Anfang
constant = ANY (array_expression)
ist nicht ganz gleichbedeutend mitarray_expression @> ARRAY[constant]
. Array-Operatoren geben einen Fehler zurück, wenn NULL- Elemente beteiligt sind, während dasANY
Konstrukt auf beiden Seiten mit NULL umgehen kann. Und es gibt unterschiedliche Ergebnisse für Datentyp-Fehlanpassungen.Verwandte Antworten:
Überprüfen Sie, ob der Wert im Postgres-Array vorhanden ist
Index zum Suchen eines Elements in einem JSON-Array
SQLAlchemy: Wie filtere ich nach PgArray-Spaltentypen?
Kann IS DISTINCT FROM irgendwie mit ANY oder ALL kombiniert werden?
Nebenbei
Berücksichtigen Sie bei der Arbeit mit
integer
Arrays (int4
, nichtint2
oderint8
) ohneNULL
Werte (wie in Ihrem Beispiel angegeben) das zusätzliche Modulintarray
, das spezialisierte, schnellere Operatoren und Indexunterstützung bietet. Sehen:Was die
UNIQUE
Einschränkung in Ihrer Frage betrifft, die unbeantwortet blieb: Diese wird mit einem btree-Index für den gesamten Array- Wert implementiert (wie Sie vermutet haben) und hilft bei der Suche nach Elementen überhaupt nicht. Einzelheiten:quelle
gin__int_ops
sei denn, sie werden fürinteger[]
Spalten verwendet. Es dauerte Jahre der Frustration und der Suche nach anderen Lösungen, bis ich diese Op-Klasse entdeckte. Es ist ein Borderline-Wundertäter.ANY (array_expression) = constant
Ausdrücke funktionieren GIN-Indizes einwandfrei?Es ist jetzt möglich, die einzelnen Array-Elemente zu indizieren. Beispielsweise:
Dies funktioniert mindestens auf Postgres 9.2.1. Beachten Sie, dass Sie für jeden Array-Index einen eigenen Index erstellen müssen. In meinem Beispiel habe ich nur das erste Element indiziert.
quelle