Seus outros dois índices não funcionarão simplesmente porque o
->>
operador retorna text
, enquanto você obviamente tem o jsonb
classes de operadores de gin em mente. Observe que você menciona apenas json
, mas na verdade você precisa de jsonb
para recursos avançados de indexação. Para elaborar a melhor estratégia de indexação, você teria que definir mais detalhadamente quais consultas cobrir. Você só está interessado em vacas? Ou todos os animais / todas as tags? Quais operadores são possíveis? Seu documento JSON também inclui chaves não animais? O que fazer com aqueles? Deseja incluir linhas no índice em que vacas (ou qualquer outra coisa) não apareçam no documento JSON?
Supondo:
- Estamos interessados apenas em vacas no primeiro nível de nidificação.
- O valor é sempre um
integer
válido . - Não estamos interessados em filas sem vacas.
Eu sugiro um índice btree funcional, bem como você já tem, mas converta o valor para
integer
. Acho que você não gostaria que a comparação fosse avaliada como text
(onde '2' é maior que '1111'). CREATE INDEX animal_index ON farm (((animal ->> 'cow')::int)); -- !
O conjunto extra de parênteses é necessário para que a abreviação de conversão torne a sintaxe da expressão de índice inequívoca.
Use a mesma expressão em suas consultas para fazer o Postgres perceber que o índice é aplicável:
SELECT * FROM farm WHERE (animal ->> 'cow')::int > 3;
Se você precisar de um
jsonb
mais genérico índice, considere:- Qual é o índice adequado para consultar estruturas em arrays no Postgres jsonb?
Para um conhecido, estático, trivial número de animais (como você comentou), sugiro índices parciais como:
CREATE INDEX animal_index ON farm (((animal ->> 'cow')::int))
WHERE (animal ->> 'cow') IS NOT NULL;
CREATE INDEX animal_index ON farm (((animal ->> 'chicken')::int))
WHERE (animal ->> 'chicken') IS NOT NULL;
etc.
Talvez seja necessário adicionar a condição de índice à consulta:
SELECT * FROM farm
WHERE (animal ->> 'cow')::int > 3
AND (animal ->> 'cow') IS NOT NULL;
Pode parecer redundante, mas pode ser necessário. Teste com
ANALYZE
!