PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Beschleunigen Sie den Bereichstest für Schlüsselwerte, die in einem jsonb-Array von Objekten verschachtelt sind

Eine erste Sofortmaßnahme wäre, die Abfrage etwas schneller zu machen:

SELECT *
FROM   parents p
WHERE  EXISTS (
   SELECT FROM jsonb_array_elements(p.children) c
   WHERE (c->>'age')::int BETWEEN 10 AND 12
   );

Der EXISTS Semi-Join vermeidet die Duplizierung von Zeilen in der Zwischentabelle, wenn mehrere Array-Objekte übereinstimmen - und die Notwendigkeit von DISTINCT ON in der äußeren Abfrage. Aber das ist nur geringfügig schneller.

Das Kernproblem besteht darin, dass Sie auf einen Bereich ganzzahliger Werte testen möchten , während vorhandene jsonb Operatoren stellen solche Funktionen nicht bereit.

Es gibt verschiedene Möglichkeiten, dies zu umgehen. Nichts davon wissend, hier ist eine "intelligente" Lösung, die das gegebene Beispiel löst. Der Trick besteht darin, den Bereich in verschiedene Werte aufzuteilen und den jsonb zu verwenden Containment-Operator @> :

SELECT *
FROM   parents p
WHERE (p.children @> '[{"age": 10}]'
OR     p.children @> '[{"age": 11}]'
OR     p.children @> '[{"age": 12}]');

Unterstützt von einem jsonb_path_ops GIN-Index:

CREATE INDEX parents_children_gin_idx ON parents USING gin (children jsonb_path_ops);

Wenn Ihre Bereiche jedoch mehr als eine Handvoll ganzzahliger Werte umfassen, benötigen Sie etwas Allgemeineres. Wie immer , die beste Lösung hängt von der Gesamtsituation ab:Datenverteilung, Wertehäufigkeiten, typische Bereiche in Abfragen, NULL-Werte möglich?, Zeilengröße, Lese-/Schreibmuster, funktioniert jeder jsonb Wert haben mindestens ein übereinstimmendes age Schlüssel? ...

Verwandte Antwort mit spezialisiertem, sehr schnellem Index:

Verwandte: