最初の直接的な対策は、クエリを少し速くすることです。
SELECT *
FROM parents p
WHERE EXISTS (
SELECT FROM jsonb_array_elements(p.children) c
WHERE (c->>'age')::int BETWEEN 10 AND 12
);
EXISTS
半結合は、複数の配列オブジェクトが一致する場合に中間テーブルの行の重複を回避します-そしてDISTINCT ON
の必要性 外側のクエリで。しかし、それはまだわずかに速いだけです。
中心的な問題は、整数値の範囲をテストすることです。 、既存のjsonb
演算子
そのような機能を提供しないでください。
これにはさまざまな方法があります。これについて何も知らないので、ここに与えられた例を解決する「賢い」解決策があります。秘訣は、範囲を個別の値に分割し、jsonb
を使用することです。 封じ込め演算子@>
:
SELECT *
FROM parents p
WHERE (p.children @> '[{"age": 10}]'
OR p.children @> '[{"age": 11}]'
OR p.children @> '[{"age": 12}]');
jsonb_path_ops
でサポートされています GINインデックス:
CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);
ただし、範囲が整数値でいっぱいの手以上に及ぶ場合は、より一般的なものが必要になります。 常にとして 、最善の解決策は、完全な状況によって異なります。データの分散、値の頻度、クエリの一般的な範囲、NULL値の可能性、行サイズ、読み取り/書き込みパターン、すべて jsonb
値に一致するage
が1つ以上あります 鍵? ...
専門的で非常に高速なインデックスに関連する回答:
関連: