Index Only Scan обращается к таблице: смотрим Heap Fetches
Для частого отчёта создан покрывающий индекс: ключ фильтра плюс INCLUDE с суммой заказа. В плане появился Index Only Scan, но число Heap Fetches остаётся высоким. Ожидание было простым: все нужные столбцы лежат в индексе, значит таблица больше не нужна.
PostgreSQL должен проверить видимость версии строки для снимка транзакции. Когда visibility map подтверждает, что страница содержит только видимые всем строки, чтение heap можно пропустить. Если подтверждения нет, даже Index Only Scan обращается к таблице.
Как изменить решение
CREATE INDEX orders_customer_cover_idx
ON orders (customer_id) INCLUDE (amount);
EXPLAIN (ANALYZE, BUFFERS)
SELECT amount FROM orders WHERE customer_id = 42;Смотрите не только имя узла, но и Heap Fetches. На часто обновляемой таблице этот показатель может оставаться заметным. На стабильных исторических данных после обычного обслуживания шанс чтения без heap выше.
INCLUDE стоит добавлять для часто читаемых небольших значений. Широкий JSON или длинный текст увеличивает индекс и стоимость изменения данных. Покрытие всего SELECT * обычно разрушает первоначальную идею небольшого индекса под конкретную выборку.
Что проверить на своих данных
На тестовой таблице сравните план после загрузки, затем после VACUUM и после серии UPDATE. VACUUM выполняйте отдельной командой вне транзакционного блока. Сохраняйте Heap Fetches и буферную статистику вместе с временем: на прогретом кэше разница во времени может быть небольшой, хотя объём обращений изменился.
Если отчёт читает большую долю таблицы, последовательный план тоже может оказаться выгодным. Покрывающий индекс не гарантирует лучшую стратегию для любого customer_id. Сравните клиента с несколькими заказами и клиента с большой историей, иначе локальный удачный замер легко принять за правило для всех значений параметра.
Практика дальше
Следующая практика — запросы, где правильность зависит от нескольких источников и граничных случаев. В курсе «Продвинутый SQL» вы решаете 109 задач на JOIN, окна и CTE, сверяете отчёты и собираете витрину интернет-магазина. Запросы выполняются в браузере на SQLite с автоматической проверкой.
Посмотреть программу и практику курса
Источник: Index Only Scan обращается к таблице — официальная документация.
Другие задачи по теме: PostgreSQL: запись, блокировки и планы запросов.
Продолжить на практике
- Продвинутый SQL: сложные запросы и задачи для собеседований ↗
Продолжение базового SQL: сложные JOIN, оконные рамки, временные ряды, retention, воронки и рекурсивные CTE. Разбирайте примеры и пишите запросы с автоматической проверкой — от отдельных расчётов до витрины интернет-магазина.
