PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Accélérer le test de plage pour les valeurs clés imbriquées dans le tableau d'objets jsonb

Une première mesure immédiate serait de rendre la requête que vous avez un peu plus rapide :

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

Le EXISTS la semi-jointure évite la duplication des lignes dans la table intermédiaire lorsque plusieurs objets de tableau correspondent - et le besoin de DISTINCT ON dans la requête externe. Mais ce n'est encore que légèrement plus rapide.

Le problème principal est que vous voulez tester une plage de valeurs entières , tandis que jsonb opérateurs ne fournissent pas une telle fonctionnalité.

Il existe différentes façons de contourner cela. Ne sachant rien de tout cela, voici une solution "intelligente" qui résout l'exemple donné. L'astuce consiste à diviser la plage en valeurs distinctes et à utiliser le jsonb opérateur de confinement @> :

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

Pris en charge par un jsonb_path_ops Indice GIN :

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

Mais si vos plages s'étendent sur plus d'une poignée de valeurs entières, vous aurez besoin de quelque chose de plus générique. Comme toujours , la meilleure solution dépend de la situation complète :distribution des données, fréquences des valeurs, plages types dans les requêtes, valeurs NULL possibles ?, taille des lignes, modèles de lecture/écriture, est-ce que chaque jsonb valeur ont un ou plusieurs age correspondants clé? ...

Réponse connexe avec index spécialisé et très rapide :

Connexe :