La differenza nel tempo di esecuzione della query è perché la prima esecuzione deve leggere molti più blocchi da 8kB dal disco:confronta shared read=631496
e shared read=30359
.
PostgreSQL decide di non utilizzare l'indice per WHERE
condizione, ma l'indice che supporta il ORDER BY
. Nota che a causa di IN
non è possibile utilizzare un indice per entrambi i WHERE
condizione e il ORDER BY
– questo è possibile solo per WHERE
condizioni che utilizzano =
come operatore di confronto.
Quindi PostgreSQL deve fare una scelta, e probabilmente fa quella sbagliata:poiché le sue statistiche dicono all'ottimizzatore che ci sono molte righe che soddisfano il WHERE
condizione, decide di leggere le righe in ORDER BY
ordina e scarta quelli che non corrispondono a WHERE
condizione finché non ha trovato 100 righe di risultati. Sfortunatamente, sembra che le righe corrispondenti non siano vicine all'inizio della tabella e PostgreSQL deve scansionare molte righe (Rows Removed by Filter: 17276154
).
Per farlo usa una scansione dell'indice per WHERE
condizione, modificare il ORDER BY
clausola in modo che PostgreSQL non possa utilizzare un indice per esso:
ORDER BY datetime + INTERVAL '0 seconds' DESC
Poiché qui non è possibile utilizzare un indice a più colonne, l'indice migliore sarebbe
CREATE INDEX ON report (sensor_id);