Пропуски Middle Индексы обновлено

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;

Попробуйте сами

Заполните пропуски по номерам.

1
2
Показать ответ и разбор

Коротко

Если все нужные колонки есть в индексе, PostgreSQL выбирает Index Only Scan и читает только индекс. Но проверять видимость версий строк всё равно нужно, и индекс этого не умеет, поэтому для страниц, не помеченных в visibility map как all-visible, идёт обращение к таблице (Heap Fetches).

Что в пропусках

1

Index Only Scan

2

VACUUM или VACUUM ANALYZE

Разбор

Если все нужные колонки есть в индексе, PostgreSQL выбирает Index Only Scan и читает только индекс. Но проверять видимость версий строк всё равно нужно, и индекс этого не умеет, поэтому для страниц, не помеченных в visibility map как all-visible, идёт обращение к таблице (Heap Fetches). Пометки ставит VACUUM (обычно autovacuum). ANALYZE сам по себе только собирает статистику и карту видимости не обновляет, а VACUUM ANALYZE делает и то, и другое.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.