Index Only Scan и visibility map
Вопрос
Запрос выбирает только created_at по диапазону, есть индекс по created_at. Заполни пропуск в плане (узел, который не читает таблицу) и команду, которая после массовых изменений вернёт Heap Fetches к нулю.
__(1)__ using orders_created_at_idx on orders (cost=0.42..88.05 rows=2781 width=8) (actual time=0.100..0.380 rows=2880 loops=1)
Index Cond: ((created_at >= '2024-03-01 00:00:00+00'::timestamp with time zone) AND (created_at < '2024-03-02 00:00:00+00'::timestamp with time zone))
Heap Fetches: 0
-- после массового UPDATE:
__(2)__ orders;
Попробуйте сами
Заполните пропуски по номерам.
Показать ответ и разбор
Коротко
Что в пропусках
Index Only Scan
VACUUM или VACUUM ANALYZE
Разбор
Если все нужные колонки есть в индексе, PostgreSQL выбирает Index Only Scan и читает только индекс. Но проверять видимость версий строк всё равно нужно, и индекс этого не умеет, поэтому для страниц, не помеченных в visibility map как all-visible, идёт обращение к таблице (Heap Fetches). Пометки ставит VACUUM (обычно autovacuum). ANALYZE сам по себе только собирает статистику и карту видимости не обновляет, а VACUUM ANALYZE делает и то, и другое.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.