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
integervá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 !