@Tregoreg ha sollevato una domanda nel commento alla sua generosità offerta:
Non ho trovato le risposte attuali funzionanti. L'uso dell'indice GIN sulla colonna tipizzata da array non aumenta le prestazioni dell'operatore ANY (). Non c'è davvero nessuna soluzione?
@ La risposta accettata da Frank ti dice di usare gli operatori di array , che è ancora corretto per Postgres 11. Il manuale:
... la distribuzione standard di PostgreSQL include una classe operatore GIN per array, che supporta query indicizzate utilizzando questi operatori:
<@
@>
=
&&
L'elenco completo delle classi di operatori integrate per gli indici GIN nella distribuzione standard è qui.
In Postgres gli indici sono associati ad operatori (che sono implementati per determinati tipi), non solo a tipi di dati o funzioni o altro. Questa è un'eredità dal design originale Berkeley di Postgres e molto difficile da cambiare ora. E generalmente funziona bene. Ecco una discussione su pgsql-bugs con Tom Lane che commenta questo.
Alcune funzioni di PostGis (come ST_DWithin()
) sembrano violare questo principio, ma non è così. Tali funzioni vengono riscritte internamente per utilizzare i rispettivi operatori .
L'espressione indicizzata deve essere alla sinistra dell'operatore. Per la maggior parte degli operatori ( incluso tutto quanto sopra ) il pianificatore di query può ottenere questo risultato capovolgendo gli operandi se si posiziona l'espressione indicizzata a destra, dato che a COMMUTATOR
è stato definito. Il ANY
costrutto può essere utilizzato in combinazione con vari operatori e non è un operatore stesso. Se utilizzato come constant = ANY (array_expression)
solo indici che supportano l' =
operatore sugli elementi dell'array, si qualificherebbe e avremmo bisogno di un commutatore = ANY()
. Gli indici GIN sono fuori.
Postgres non è attualmente abbastanza intelligente da derivarne un'espressione indicizzabile GIN. Per cominciare, nonconstant = ANY (array_expression)
è del tutto equivalente a array_expression @> ARRAY[constant]
. Gli operatori di matrice restituiscono un errore se sono coinvolti elementi NULL , mentre il ANY
costrutto può gestire NULL su entrambi i lati. E ci sono risultati diversi per le discrepanze tra i tipi di dati.
Risposte correlate:
asides
Mentre si lavora con integer
array ( int4
, non int2
o int8
) senza NULL
valori (come suggerisce l'esempio), prendere in considerazione il modulo aggiuntivo intarray
, che fornisce agli operatori specializzati, più veloci e supporto agli indici. Vedere:
Per quanto riguarda il UNIQUE
vincolo della tua domanda che è rimasto senza risposta: è implementato con un indice btree sull'intero valore dell'array (come sospettavi) e non aiuta affatto nella ricerca di elementi . Dettagli:
jsonb
e utilizzare gli indici? postgresql.org/docs/9.5/static/functions-json.html e postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXING