Não consigo encontrar uma resposta definitiva para esta pergunta na documentação. Se uma coluna for do tipo matriz, todos os valores inseridos serão indexados individualmente?
Criei uma tabela simples com uma int[]
coluna e coloquei um índice exclusivo. Percebi que não era possível adicionar a mesma matriz de entradas, o que me leva a acreditar que o índice é um composto dos itens da matriz, não um índice de cada item.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
O índice está ajudando esta consulta?
arrays
postgresql
indexing
IamIC
fonte
fonte
jsonb
e os índices? postgresql.org/docs/9.5/static/functions-json.html e postgresql.org/docs/9.5/static/datatype-json.html#JSON-INDEXINGRespostas:
Sim, você pode indexar uma matriz, mas é necessário usar os operadores da matriz e o tipo de índice GIN .
Exemplo:
Resultado:
Notaparece que em muitos casos a opção gin__int_ops é necessária
Ainda não vi um caso em que funcionaria com o operador && e @> sem as opções gin__int_ops
fonte
gin__int_ops
sejam usados parainteger[]
colunas. Levei anos de frustração e procurando outras soluções até descobrir essa classe operacional. É um milagreiro limítrofe.@Tregoreg levantou uma pergunta no comentário para sua recompensa oferecida:
@ A resposta aceita por Frank diz para você usar operadores de matriz , o que ainda está correto para o Postgres 11. O manual:
A lista completa de classes de operadores internas para índices GIN na distribuição padrão está aqui.
No Postgres, os índices são vinculados aos operadores (que são implementados para certos tipos), não apenas tipos de dados, funções ou qualquer outra coisa. Essa é uma herança do design original do Postgres de Berkeley e muito difícil de mudar agora. E geralmente está funcionando muito bem. Aqui está um tópico sobre pgsql-bugs com Tom Lane comentando sobre isso.
Algumas funções do PostGis (como
ST_DWithin()
) parecem violar esse princípio, mas não é assim. Essas funções são reescritas internamente para usar os respectivos operadores .A expressão indexada deve estar à esquerda do operador. Para a maioria dos operadores ( incluindo todos os itens acima ), o planejador de consultas pode conseguir isso invertendo operandos se você colocar a expressão indexada à direita - desde que a
COMMUTATOR
tenha sido definida. AANY
construção pode ser usada em combinação com vários operadores e não é um operador em si. Quando usado comoconstant = ANY (array_expression)
apenas índices que suportam o=
operador em elementos da matriz se qualificariam e precisaríamos de um comutador para= ANY()
. Os índices GIN estão fora.Atualmente, o Postgres não é inteligente o suficiente para derivar uma expressão indexável a GIN. Para iniciantes, não
constant = ANY (array_expression)
é completamente equivalente aarray_expression @> ARRAY[constant]
. Os operadores de matriz retornam um erro se houver algum elemento NULL envolvido, enquanto aANY
construção pode lidar com NULL em ambos os lados. E há resultados diferentes para incompatibilidades de tipo de dados.Respostas relacionadas:
Verifique se o valor existe na matriz do Postgres
Índice para localizar um elemento em uma matriz JSON
SQLAlchemy: como filtrar os tipos de coluna PgArray?
O DISTINCT FROM pode ser combinado com QUALQUER ou TUDO de alguma forma?
Apartes
Ao trabalhar com
integer
matrizes (int4
, nãoint2
ouint8
) semNULL
valores (como o seu exemplo indica), considere o módulo adicionalintarray
, que fornece operadores mais rápidos e especializados e suporte ao índice. Vejo:Quanto à
UNIQUE
restrição em sua pergunta que ficou sem resposta: isso é implementado com um índice btree em todo o valor da matriz (como você suspeitava) e não ajuda na busca de elementos . Detalhes:fonte
gin__int_ops
sejam usados parainteger[]
colunas. Levei anos de frustração e procurando outras soluções até descobrir essa classe operacional. É um milagreiro limítrofe.ANY (array_expression) = constant
expressões, os índices GIN funcionam bem?Agora é possível indexar os elementos individuais da matriz. Por exemplo:
Isso funciona pelo menos no Postgres 9.2.1. Observe que você precisa criar um índice separado para cada índice de matriz. No meu exemplo, indexei apenas o primeiro elemento.
fonte