Prvním okamžitým opatřením by bylo trochu zrychlit dotaz, který máte:
SELECT *
FROM parents p
WHERE EXISTS (
SELECT FROM jsonb_array_elements(p.children) c
WHERE (c->>'age')::int BETWEEN 10 AND 12
);
EXISTS
semi-join zabraňuje duplikaci řádků v přechodné tabulce, když se shoduje více objektů pole – a potřeba DISTINCT ON
ve vnějším dotazu. Ale to je zatím jen mírně rychlejší.
Hlavním problémem je, že chcete testovat rozsah celočíselných hodnot , zatímco existuje jsonb
operátorů
takovou funkci neposkytují.
Existují různé způsoby, jak to obejít. Když nic z toho nevíte, tady je „chytré“ řešení, které daný příklad řeší. Trik je rozdělit rozsah na různé hodnoty a použít jsonb
operátor kontejnmentu @>
:
SELECT *
FROM parents p
WHERE (p.children @> '[{"age": 10}]'
OR p.children @> '[{"age": 11}]'
OR p.children @> '[{"age": 12}]');
Podporováno jsonb_path_ops
Index GIN:
CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);
Ale pokud vaše rozsahy zabírají více než ruku plnou celočíselných hodnot, budete potřebovat něco obecnějšího. Jako vždy , nejlepší řešení závisí na celkové situaci:Distribuce dat, frekvence hodnot, typické rozsahy v dotazech, možné hodnoty NULL?, velikost řádku, vzory čtení/zápisu, každý jsonb
hodnota má jeden nebo více odpovídajících age
klíč? ...
Související odpověď se specializovaným, velmi rychlým indexem:
Související: