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 :
-
Normalisez votre conception. La désimbrication des documents JSON n'est pas gratuite.
-
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...