Zakładając id
nie tylko UNIQUE
- zgodnie z Twoim UNIQUE INDEX
- ale także NOT NULL
. (Brakuje tego w definicji tabeli).
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;
Krótszy odpowiednik:
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
był szum, ponieważ następujący test WHERE meta_split.value IS NOT NULL
wymusza INNER JOIN
w każdym razie. Używanie CROSS JOIN
zamiast tego.
Również, ponieważ jsonb
i tak nie zezwala na duplikowanie kluczy na tym samym poziomie (co oznacza ten sam id
może pojawić się tylko raz na (key, value)
), DISTINCT
to po prostu drogi hałas. count(v.id)
robi to samo taniej. I count(*)
jest równoważny i tańszy, ale - zakładając id
jest NOT NULL
jak podano na górze.
count(*)
ma osobną implementację
i jest nieco szybszy niż count(<value>)
. Różni się nieco od count(v.*)
. Liczy wszystkie rzędy, bez względu na wszystko. Podczas gdy druga forma się nie liczy NULL
wartości.
To znaczy, o ile id
nie może być NULL
- jak podano na górze. id
naprawdę powinien być PRIMARY KEY
, który i tak jest zaimplementowany wewnętrznie z unikalnym indeksem B-drzewa i wszystkimi kolumnami - po prostu id
tutaj - są NOT NULL
niejawnie. Lub przynajmniej NOT NULL
. UNIQUE INDEX
nie kwalifikuje się w pełni jako zamiennik, nadal zezwala na NULL
wartości, które nie są uważane za równe i są dozwolone wielokrotnie. Zobacz:
Poza tym indeksy na nic się tu nie przydadzą, bo i tak wszystkie wiersze muszą być odczytane. Więc to nigdy nie będzie bardzo tanie. Ale 62 tys. wierszy nie jest w żaden sposób paraliżującą liczbą wierszy - chyba że masz ogromną liczbę kluczy w jsonb
kolumna.
Pozostałe opcje przyspieszenia:
-
Normalizuj swój projekt. Rozpakowywanie dokumentów JSON nie jest bezpłatne.
-
Zachowaj zmaterializowany widok. Wykonalność i koszty silnie zależą od Twoich wzorców pisania.
W tym miejscu indeksy mogą ponownie odgrywać rolę ...