Pierwszym natychmiastowym działaniem byłoby przyspieszenie zapytania:
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 zapobiega duplikowaniu wierszy w tabeli pośredniej, gdy wiele obiektów tablicy pasuje - i potrzeba DISTINCT ON
w zewnętrznym zapytaniu. Ale to tylko trochę szybciej.
Podstawowym problemem jest to, że chcesz przetestować zakres wartości całkowitych , podczas gdy istniejący jsonb
operatorzy
nie zapewniają takiej funkcjonalności.
Można to obejść na różne sposoby. Nie wiedząc o tym wszystkim, oto „inteligentne” rozwiązanie, które rozwiązuje podany przykład. Sztuczka polega na podzieleniu zakresu na różne wartości i użyciu jsonb
operator zawartości @>
:
SELECT *
FROM parents p
WHERE (p.children @> '[{"age": 10}]'
OR p.children @> '[{"age": 11}]'
OR p.children @> '[{"age": 12}]');
Obsługiwane przez jsonb_path_ops
Indeks WZ:
CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);
Ale jeśli twoje zakresy obejmują więcej niż rękę pełną wartości całkowitych, potrzebujesz czegoś bardziej ogólnego. Jak zawsze , najlepsze rozwiązanie zależy od całej sytuacji:rozkład danych, częstości wartości, typowe zakresy w zapytaniach, możliwe wartości NULL?, rozmiar wiersza, wzorce odczytu/zapisu, czy każda jsonb
wartość ma co najmniej jeden pasujący age
klucz? ...
Powiązana odpowiedź z wyspecjalizowanym, bardzo szybkim indeksem:
Powiązane: