PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Acelere o teste de intervalo para valores de chave aninhados na matriz de objetos jsonb


Uma primeira medida imediata seria tornar a consulta que você tem um pouco mais rápida:
SELECT *
FROM   parents p
WHERE  EXISTS (
   SELECT FROM jsonb_array_elements(p.children) c
   WHERE (c->>'age')::int BETWEEN 10 AND 12
   );

O EXISTE semi-join evita a duplicação de linhas na tabela intermediária quando vários objetos de matriz correspondem - e a necessidade de DISTINCT ON na consulta externa. Mas isso é apenas ligeiramente mais rápido, ainda.

O problema principal é que você deseja testar um intervalo de valores inteiros , enquanto jsonb existente operadores não fornecem tal funcionalidade.

Existem várias maneiras de contornar isso. Sem saber nada disso, aqui está uma solução "inteligente" que resolve o exemplo dado. O truque é dividir o intervalo em valores distintos e usar o jsonb operador de contenção @> :
SELECT *
FROM   parents p
WHERE (p.children @> '[{"age": 10}]'
OR     p.children @> '[{"age": 11}]'
OR     p.children @> '[{"age": 12}]');

Suportado por um jsonb_path_ops Índice GIN:
CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);

Mas se seus ranges abrangem mais do que uma mão cheia de valores inteiros, você precisará de algo mais genérico. Como sempre , a melhor solução depende da situação completa:distribuição de dados, frequências de valores, intervalos típicos em consultas, valores NULL possíveis?, tamanho da linha, padrões de leitura/gravação, todos jsonb value tem um ou mais age correspondentes chave? ...

Resposta relacionada com índice especializado e muito rápido:

Relacionado: