@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 ANYcostrutto 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 ANYcostrutto 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 integerarray ( int4, non int2o int8) senza NULLvalori (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 UNIQUEvincolo 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:
jsonbe utilizzare gli indici? postgresql.org/docs/9.5/static/functions-json.html e postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXING