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

Optimisation de GROUP BY + COUNT DISTINCT sur une colonne jsonb non imbriquée

En supposant id non seulement UNIQUE - comme imposé par votre UNIQUE INDEX - mais aussi NOT NULL . (Cela manque dans la définition de votre table.)

SELECT meta_split.key, meta_split.value, count(*)
FROM   voc_cc348779bdc84f8aab483f662a798a6a v
CROSS  JOIN LATERAL jsonb_each(v.meta) AS meta_split
GROUP  BY meta_split.key, meta_split.value;

Équivalent plus court :

SELECT meta_split.key, meta_split.value, count(*)
FROM   voc_cc348779bdc84f8aab483f662a798a6a v, jsonb_each(v.meta) AS meta_split
GROUP  BY 1, 2;

La LEFT [OUTER] JOIN était du bruit car le test suivant WHERE meta_split.value IS NOT NULL force un INNER JOIN De toute façon. Utilisation de CROSS JOIN à la place.

De plus, depuis jsonb n'autorise pas les clés en double au même niveau de toute façon (c'est-à-dire le même id ne peut apparaître qu'une fois par (key, value) ), DISTINCT est juste un bruit coûteux. count(v.id) fait la même chose moins cher. Et count(*) est équivalent et moins cher, mais - en supposant id est NOT NULL comme indiqué en haut.

count(*) a une implémentation distincte et est légèrement plus rapide que count(<value>) . C'est subtilement différent de count(v.*) . Il compte toutes les lignes, quoi qu'il arrive. Alors que l'autre forme ne compte pas NULL valeurs.

Autrement dit, tant que id ne peut pas être NULL - comme indiqué en haut. id devrait vraiment être la PRIMARY KEY , qui est implémenté avec un index B-tree unique en interne de toute façon, et toutes les colonnes - juste id ici - sont NOT NULL implicitement. Ou au moins NOT NULL . Un UNIQUE INDEX n'est pas entièrement qualifié de remplacement, il autorise toujours NULL valeurs qui ne sont pas considérées comme égales et sont autorisées plusieurs fois. Voir :

En dehors de cela, les index ne sont d'aucune utilité ici, car toutes les lignes doivent être lues de toute façon. Donc, ce ne sera jamais très bon marché. Mais 62k lignes n'est en aucun cas un nombre de lignes paralysant - à moins que vous n'ayez un grand nombre de clés dans le jsonb colonne.

Les options restantes pour l'accélérer :

  1. Normalisez votre conception. La désimbrication des documents JSON n'est pas gratuite.

  2. Maintenir une vue matérialisée. La faisabilité et les coûts dépendent fortement de vos habitudes d'écriture.

C'est là que les index peuvent à nouveau jouer un rôle...