Приемайки id
не само UNIQUE
- както се налага от вашия UNIQUE INDEX
- но също и NOT NULL
. (Това липсва в дефиницията на вашата таблица.)
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;
По-кратък еквивалент:
SELECT meta_split.key, meta_split.value, count(*)
FROM voc_cc348779bdc84f8aab483f662a798a6a v, jsonb_each(v.meta) AS meta_split
GROUP BY 1, 2;
LEFT [OUTER] JOIN
беше шум, защото следният тест WHERE meta_split.value IS NOT NULL
налага INNER JOIN
така или иначе. Използване на CROSS JOIN
вместо това.
Освен това, тъй като jsonb
така или иначе не позволява дублиране на ключове на едно и също ниво (което означава същия id
може да изскочи само веднъж за (key, value)
), DISTINCT
е просто скъп шум. count(v.id)
прави същото по-евтино. И count(*)
е еквивалентен и по-евтин, но все пак - ако приемем id
е NOT NULL
както е посочено в горната част.
count(*)
има отделна реализация
и е малко по-бърз от count(<value>)
. Той е леко различен от count(v.*)
. Той брои всички редове, без значение какво. Докато другата форма не брои NULL
стойности.
Тоест, докато id
не може да бъде NULL
- както е посочено в горната част. id
наистина трябва да е PRIMARY KEY
, който така или иначе е имплементиран с уникален индекс на B-дърво вътрешно, и всички колони - само id
тук - са NOT NULL
имплицитно. Или поне NOT NULL
. UNIQUE INDEX
не се квалифицира напълно като замяна, той все още позволява NULL
стойности, които не се считат за равни и са разрешени няколко пъти. Вижте:
Освен това тук индексите не са от полза, тъй като така или иначе всички редове трябва да се четат. Така че това никога няма да бъде много евтино. Но 62k реда не е осакатяващ брой редове по никакъв начин - освен ако нямате огромен брой ключове в jsonb
колона.
Останалите опции за ускоряване:
-
Нормализирайте дизайна си. Премахването на JSON документи не е безплатно.
-
Поддържайте материализиран изглед. Осъществимостта и разходите силно зависят от вашите модели на запис.
Това е мястото, където индексите могат отново да играят роля...