Je ne trouve pas de réponse définitive à cette question dans la documentation. Si une colonne est de type tableau, toutes les valeurs entrées seront-elles indexées individuellement?
J'ai créé une table simple avec une int[]
colonne et y ai mis un index unique. J'ai remarqué que je ne pouvais pas ajouter le même tableau d'entiers, ce qui me porte à croire que l'index est un composite des éléments du tableau, pas un index de chaque élément.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
L'index aide-t-il cette requête?
arrays
postgresql
indexing
IamIC
la source
la source
jsonb
et d'utiliser les index? postgresql.org/docs/9.5/static/functions-json.html et postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXINGRéponses:
Oui, vous pouvez indexer un tableau, mais vous devez utiliser les opérateurs de tableau et le type d'index GIN .
Exemple:
Résultat:
Remarqueil semble que dans de nombreux cas, l' option gin__int_ops soit requise
Je n'ai pas encore vu de cas où cela fonctionnerait avec l'opérateur && et @> sans les options gin__int_ops
la source
gin__int_ops
soient utilisés pour lesinteger[]
colonnes. Il m'a fallu des années de frustration et de recherche d'autres solutions avant de découvrir cette classe d'opérations. C'est un faiseur de miracles à la limite.@Tregoreg a soulevé une question dans le commentaire sur sa prime offerte:
@ La réponse acceptée de Frank vous indique d'utiliser des opérateurs de tableau , ce qui est toujours correct pour Postgres 11. Le manuel:
La liste complète des classes d'opérateurs intégrées pour les index GIN dans la distribution standard se trouve ici.
Dans Postgres, les index sont liés à des opérateurs (qui sont implémentés pour certains types), pas à des types de données seuls ou à des fonctions ou autre. C'est un héritage de la conception Berkeley originale de Postgres et il est très difficile de changer maintenant. Et cela fonctionne généralement très bien. Voici un fil de discussion sur pgsql-bugs avec Tom Lane commentant cela.
Certaines fonctions PostGis (comme
ST_DWithin()
) semblent enfreindre ce principe, mais ce n'est pas le cas. Ces fonctions sont réécrites en interne pour utiliser les opérateurs respectifs .L'expression indexée doit être à gauche de l'opérateur. Pour la plupart des opérateurs ( y compris tout ce qui précède ), le planificateur de requêtes peut y parvenir en inversant les opérandes si vous placez l'expression indexée à droite - étant donné que a
COMMUTATOR
a été défini. LaANY
construction peut être utilisée en combinaison avec divers opérateurs et n'est pas un opérateur en soi. Lorsqu'ils sont utilisés commeconstant = ANY (array_expression)
seuls index prenant en charge l'=
opérateur sur les éléments du tableau, ils sont qualifiés et nous aurions besoin d'un commutateur pour= ANY()
. Les index GIN sont sortis.Postgres n'est actuellement pas assez intelligent pour en dériver une expression indexable GIN. Pour commencer,
constant = ANY (array_expression)
n'est pas complètement équivalent àarray_expression @> ARRAY[constant]
. Les opérateurs de tableau renvoient une erreur si des éléments NULL sont impliqués, tandis que laANY
construction peut traiter NULL de chaque côté. Et il existe différents résultats pour les incohérences de types de données.Réponses connexes:
Vérifier si la valeur existe dans le tableau Postgres
Index de recherche d'un élément dans un tableau JSON
SQLAlchemy: comment filtrer sur les types de colonnes PgArray?
IS DISTINCT FROM peut-il être combiné avec ANY ou ALL?
À part
Lorsque vous travaillez avec des
integer
tableaux (int4
, pasint2
ouint8
) sansNULL
valeurs (comme votre exemple l'indique), considérez le module supplémentaireintarray
, qui fournit des opérateurs spécialisés et plus rapides et un support d'index. Voir:Quant à la
UNIQUE
contrainte dans votre question qui est restée sans réponse: elle est implémentée avec un index btree sur toute la valeur du tableau (comme vous le soupçonniez) et n'aide pas du tout à la recherche d' éléments . Détails:la source
gin__int_ops
sont utilisés pour lesinteger[]
colonnes. Il m'a fallu des années de frustration et de recherche d'autres solutions avant de découvrir cette classe d'opérations. C'est un faiseur de miracles à la limite.ANY (array_expression) = constant
expressions, les index GIN fonctionnent bien?Il est maintenant possible d'indexer les éléments individuels du tableau. Par exemple:
Cela fonctionne au moins sur Postgres 9.2.1. Notez que vous devez créer un index distinct pour chaque index de tableau, dans mon exemple, je n'ai indexé que le premier élément.
la source