@Tregoreg stellte im Kommentar zu seinem angebotenen Kopfgeld eine Frage :
Ich fand die aktuellen Antworten nicht funktionierend. Die Verwendung des GIN-Index für eine Spalte vom Typ Array erhöht die Leistung des Operators ANY () nicht. Gibt es wirklich keine Lösung?
@ Frank ist akzeptiert Antwort fordert Sie auf,Array-Operatoren zu verwenden, wasfür Postgres 11immernoch korrekt ist.Das Handbuch:
... die Standarddistribution von PostgreSQL enthält eine GIN-Operatorklasse für Arrays, die indizierte Abfragen mit diesen Operatoren unterstützt:
<@
@>
=
&&
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 als constant = 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 mit array_expression @> ARRAY[constant]
. Array-Operatoren geben einen Fehler zurück, wenn NULL- Elemente beteiligt sind, während das ANY
Konstrukt auf beiden Seiten mit NULL umgehen kann. Und es gibt unterschiedliche Ergebnisse für Datentyp-Fehlanpassungen.
Verwandte Antworten:
Nebenbei
Berücksichtigen Sie bei der Arbeit mit integer
Arrays ( int4
, nicht int2
oder int8
) ohne NULL
Werte (wie in Ihrem Beispiel angegeben) das zusätzliche Modul intarray
, 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:
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-INDEXING