Biện pháp tức thì đầu tiên là làm cho truy vấn của bạn nhanh hơn một chút:
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 tránh trùng lặp các hàng trong bảng trung gian khi nhiều đối tượng mảng khớp với nhau - và cần phải DISTINCT ON
trong truy vấn bên ngoài. Nhưng nó chỉ nhanh hơn một chút.
Vấn đề cốt lõi là bạn muốn kiểm tra phạm vi giá trị số nguyên , trong khi jsonb
toán tử
không cung cấp chức năng như vậy.
Có nhiều cách khác nhau để giải quyết vấn đề này. Không biết bất kỳ điều này, đây là một giải pháp "thông minh" để giải quyết ví dụ đã cho. Mẹo là chia phạm vi thành các giá trị riêng biệt và sử dụng jsonb
toán tử ngăn chặn @>
:
SELECT *
FROM parents p
WHERE (p.children @> '[{"age": 10}]'
OR p.children @> '[{"age": 11}]'
OR p.children @> '[{"age": 12}]');
Được hỗ trợ bởi jsonb_path_ops
Chỉ số GIN:
CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);
Nhưng nếu phạm vi của bạn trải dài hơn một tay chứa đầy các giá trị số nguyên, bạn sẽ cần một cái gì đó chung chung hơn. Như luôn luôn , giải pháp tốt nhất tùy thuộc vào tình huống hoàn chỉnh:Phân phối dữ liệu, tần suất giá trị, phạm vi điển hình trong truy vấn, giá trị NULL có thể có ?, kích thước hàng, mẫu đọc / ghi, mọi jsonb
giá trị có một hoặc nhiều age
phù hợp Chìa khóa? ...
Câu trả lời liên quan với chỉ mục chuyên biệt, rất nhanh:
Có liên quan: