Ich habe eine Tabelle, die einen Index auf (Spalte A, Spalte B) hat. Und ich führe eine Abfrage aus, die wie folgt aussieht:Postgres Abfrage mit IN ist sehr langsam
SELECT * FROM table WHERE (A, B) IN ((a_1, b_1), (a_2, b_2), ..., (a_5000, b_5000))
Diese Abfrage ist sehr langsam! Der Plan sieht so aus:
Bitmap Heap Scan on table
Recheck Cond: (((A = a_1) AND (B = b_1)) OR ((A = a_2) AND (B = b_2)) OR ...
-> BitmapOr
-> Bitmap Index Scan on idx
Index Cond: ((A = a_1) AND (B = b_1))
-> Bitmap Index Scan on idx
Index Cond: ((A = a_2) AND (B = b_2))
...(5000 other Bitmax Index Scan)
Statt einen Index mit 5000 Werten scannen zu tun, Postgres tun 5000 Index-Scan mit einem Wert in einer Zeit zu sein scheint, was erklärt, warum die Abfrage so langsam ist.
Eigentlich ist es viel schneller zu tun some wie:
SELECT * FROM table WHERE A IN (a_1, ..., a_5000)
die Ergebnisse holen und dann gefiltert werden Spalte B in der App (Python).
Ich würde wirklich bevorzugen, die Ergebnisse bereits von Postgres mit einer angemessenen Laufzeit gefiltert haben. Gibt es eine Problemumgehung?
Das ist interessant. Warum sollte es einen Unterschied machen? – zerkms
@zerkms: Die Theorie (Hoffnung) ist, dass es den Optimierer trickst, einen einzigen Index-Scan für alle Werte zu machen, anstatt einen Scan für jeden Wert. –
Es funktioniert! Der Planer verwendet tatsächlich nur ein Hashjoin. Ich finde es aber merkwürdig, dass der Planer nicht intelligent genug ist, um mit der ersten Frage umzugehen. –