Index-only scan это когда PostgreSQL забирает данные полностью из индекса, не обращаясь к реальным строкам таблицы (heap). Это сильно быстрее, потому что убирается лишний шаг чтения строк с диска.
Чтобы index-only scan реально работал, PostgreSQL должен быть уверен, что данные в индексе актуальны. Из-за реализации MVCC одна и та же строка может существовать в нескольких версиях, которые используются разными активными транзакциями.
В не оптимизированном варианте PostgreSQL пришлось бы читать реальную строку, чтобы проверить ее видимость (visibility) и при необходимости взять последнюю версию. Из-за этого index-only scans могут быть не такими быстрыми, как хотелось бы. Чтобы ускорить это, PostgreSQL использует Visibility Map.
Visibility Map это внутренняя структура данных, которую PostgreSQL ведет, чтобы отслеживать, какие страницы (блоки строк) в таблице содержат только такие tuple (строки), которые видимы всем транзакциям. Если страница помечена в visibility map как
all-visible, движок понимает, что ему не нужно проверять видимость отдельных строк на этой странице.Поэтому во время index-only scan PostgreSQL сначала вычисляет строки, которые должны попасть в результат, а потом смотрит в visibility map, помечена ли соответствующая страница как
all-visible. Если да, он пропускает чтение этой страницы из heap, и выполнение становится быстрее и эффективнее.В PostgreSQL из-за MVCC операции update и delete приводят к появлению dead tuples, и чтобы их очистить, нужен vacuum. Поэтому в процессе vacuuming:
1. удаляются dead tuples, и
2. обновляется visibility map, чтобы пометить страницы как
all-visible.Это означает, что каждая строка на этой странице видима всем транзакциям, и теперь можно пропускать heap fetch и выполнять index-only scans быстрее.
👉 @SQLPortal