sql >> Base de Datos >  >> RDS >> PostgreSQL

Acelere la prueba de rango para los valores clave anidados en la matriz de objetos jsonb

Una primera medida inmediata sería hacer la consulta que tienes un poco más rápido:

SELECT *
FROM   parents p
WHERE  EXISTS (
   SELECT FROM jsonb_array_elements(p.children) c
   WHERE (c->>'age')::int BETWEEN 10 AND 12
   );

El EXISTS semi-join evita la duplicación de filas en la tabla intermedia cuando coinciden varios objetos de matriz, y la necesidad de DISTINCT ON en la consulta externa. Pero eso es solo un poco más rápido, todavía.

El problema central es que desea probar un rango de valores enteros , mientras jsonb operadores no proporciona dicha funcionalidad.

Hay varias maneras de evitar esto. Sin saber nada de esto, aquí hay una solución "inteligente" que resuelve el ejemplo dado. El truco es dividir el rango en valores distintos y usar jsonb operador de contención @> :

SELECT *
FROM   parents p
WHERE (p.children @> '[{"age": 10}]'
OR     p.children @> '[{"age": 11}]'
OR     p.children @> '[{"age": 12}]');

Compatible con jsonb_path_ops Índice GIN:

CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);

Pero si sus rangos abarcan más de un puñado de valores enteros, necesitará algo más genérico. Como siempre , la mejor solución depende de la situación completa:distribución de datos, frecuencias de valores, rangos típicos en las consultas, ¿valores NULL posibles?, tamaño de fila, patrones de lectura/escritura, todos jsonb el valor tiene uno o más age coincidentes ¿llave? ...

Respuesta relacionada con índice especializado muy rápido:

Relacionado: