Der Unterschied in der Abfrageausführungszeit liegt darin, dass die erste Ausführung viel mehr 8-kB-Blöcke von der Festplatte lesen muss:vergleiche shared read=631496
und shared read=30359
.
PostgreSQL entscheidet sich dafür, den Index für WHERE
nicht zu verwenden Bedingung, sondern der Index, der ORDER BY
unterstützt . Beachten Sie das wegen IN
es ist nicht möglich, einen Index für beide WHERE
zu verwenden Bedingung und den ORDER BY
– das ist nur für WHERE
möglich Bedingungen, die =
verwenden als Vergleichsoperator.
PostgreSQL muss also eine Wahl treffen, und zwar wahrscheinlich die falsche:Da seine Statistiken dem Optimierer mitteilen, dass es viele Zeilen gibt, die WHERE
erfüllen Bedingung entscheidet es, die Zeilen in ORDER BY
zu lesen Ordne und verwerfe diejenigen, die nicht mit WHERE
übereinstimmen Bedingung, bis 100 Ergebniszeilen gefunden wurden. Leider scheinen die übereinstimmenden Zeilen nicht nahe am Anfang der Tabelle zu stehen, und PostgreSQL muss viele Zeilen scannen (Rows Removed by Filter: 17276154
).
Verwenden Sie dazu einen Index-Scan für WHERE
Bedingung, ändern Sie ORDER BY
-Klausel, sodass PostgreSQL keinen Index dafür verwenden kann:
ORDER BY datetime + INTERVAL '0 seconds' DESC
Da hier kein mehrspaltiger Index benötigt wird, wäre der beste Index
CREATE INDEX ON report (sensor_id);