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);