In Postgres können Sie eine IN-Klausel wie folgt angeben:
SELECT * FROM user WHERE id IN (1000, 1001, 1002)
Weiß jemand, wie viele Parameter Sie maximal an IN übergeben können?
postgresql
Alex Riley
quelle
quelle
Abfrageplan
Aber wenn Sie versuchen, 2. Abfrage:
Abfrageplan
Wir können sehen, dass Postgres eine temporäre Tabelle erstellen und sich dieser anschließen
quelle
Die Anzahl der Elemente, die Sie an die IN-Klausel übergeben, ist unbegrenzt. Wenn mehr Elemente vorhanden sind, wird es als Array betrachtet und bei jedem Scan in der Datenbank wird geprüft, ob es im Array enthalten ist oder nicht. Dieser Ansatz ist nicht so skalierbar. Verwenden Sie anstelle der IN-Klausel INNER JOIN mit der temporären Tabelle. Weitere Informationen finden Sie unter http://www.xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic/ . Wenn Sie die INNER JOIN-Skalierung gut verwenden, kann der Abfrageoptimierer Hash-Join und andere Optimierungen verwenden. Während mit der IN-Klausel für den Optimierer keine Möglichkeit besteht, die Abfrage zu optimieren. Ich habe mit dieser Änderung eine Beschleunigung von mindestens 2x festgestellt.
quelle
OR
undIN
-klauseln bedeutet, konnte ich das Problem mit Postgres 9.5 nicht bestätigen. Siehe diese Antwort .Als jemand, der mehr Erfahrung mit Oracle DB hat, war ich auch über diese Grenze besorgt. Ich habe einen Leistungstest für eine Abfrage mit ~ 10'000 Parametern in einer
IN
Liste durchgeführt und dabei Primzahlen bis zu 100'000 aus einer Tabelle mit den ersten 100'000 Ganzzahlen abgerufen, indem ich tatsächlich alle Primzahlen als Abfrageparameter aufgelistet habe .Meine Ergebnisse zeigen, dass Sie sich keine Gedanken über das Überladen des Abfrageplanoptimierers oder das Abrufen von Plänen ohne Indexverwendung machen müssen , da die Abfrage so umgewandelt wird, dass
= ANY({...}::integer[])
sie wie erwartet Indizes nutzen kann:Dieser (ziemlich alte) Thread auf der Mailingliste von pgsql-hackers weist jedoch darauf hin, dass die Planung solcher Abfragen immer noch nicht zu vernachlässigende Kosten verursacht. Nehmen Sie also mein Wort mit einem Körnchen Salz.
quelle
Wenn Sie Fragen haben wie:
Sie können die Leistung erhöhen, wenn Sie Ihre Abfrage wie folgt umschreiben:
quelle
EXPLAIN
sagt, dass es intern meinIN (...)
als neu schreibtANY ('{...}'::integer[])
.Ich habe es gerade versucht. Die Antwort lautet -> Ganzzahl außerhalb des Bereichs als 2-Byte-Wert: 32768
quelle
Möglicherweise möchten Sie diese Abfrage umgestalten, anstatt eine beliebig lange Liste von IDs hinzuzufügen. Sie können einen Bereich verwenden, wenn die IDs tatsächlich dem Muster in Ihrem Beispiel folgen:
Eine weitere Option ist das Hinzufügen einer inneren Auswahl:
quelle