Różnica w czasie wykonania zapytania polega na tym, że pierwsze wykonanie musi odczytać o wiele więcej bloków 8kB z dysku:porównaj shared read=631496
i shared read=30359
.
PostgreSQL decyduje się nie używać indeksu dla WHERE
warunek, ale indeks, który obsługuje ORDER BY
. Zauważ, że ze względu na IN
nie jest możliwe użycie jednego indeksu dla obu WHERE
warunek i ORDER BY
– jest to możliwe tylko dla WHERE
warunki, które używają =
jako operator porównania.
PostgreSQL musi więc dokonać wyboru i prawdopodobnie dokonuje złego:ponieważ jego statystyki mówią optymalizatorowi, że istnieje wiele wierszy, które spełniają warunek WHERE
warunek, postanawia odczytać wiersze w ORDER BY
zamów i odrzuć te, które nie pasują do WHERE
warunek, dopóki nie znajdzie 100 wierszy wyników. Niestety wygląda na to, że pasujące wiersze nie znajdują się blisko początku tabeli, a PostgreSQL musi przeskanować wiele wierszy (Rows Removed by Filter: 17276154
).
Aby to zrobić, użyj skanowania indeksu dla WHERE
warunek, zmodyfikuj ORDER BY
klauzula, aby PostgreSQL nie mógł użyć do niego indeksu:
ORDER BY datetime + INTERVAL '0 seconds' DESC
Ponieważ nie ma tu zastosowania indeks wielokolumnowy, najlepszym indeksem będzie
CREATE INDEX ON report (sensor_id);