Методы доступа к данным (PostgreSQL)

PostgreSQL читает данные страницами (pages), а не “по строкам”. Поэтому главный вопрос: сколько страниц прочитаем/запишем и какой паттерн I/O.

Связанные темы:

Страницы, heap и TOAST

Планировщик запросов и EXPLAIN

ANALYZE и статистика планировщика

Индексы в PostgreSQL


Основные методы сканирования

Seq Scan (последовательное сканирование)

  • Читает таблицу целиком (heap).

  • Часто быстрее индекса, если нужно вернуть большую долю таблицы (много строк) или таблица маленькая.

  • Риск: “случайно” просканировать гигантскую таблицу из-за неверного фильтра/плана.

Index Scan (индексное сканирование)

  • Идёт по индексу и для каждой найденной записи обычно читает соответствующую страницу heap.

  • Хорошо, когда возвращаем мало строк и фильтр селективный.

  • Может стать дорогим при большом числе попаданий: будет много случайных чтений heap.

Bitmap Index Scan + Bitmap Heap Scan

  • Сначала строит “битовую карту” подходящих TID, затем читает heap более пакетно.

  • Полезно, когда строк “не совсем мало”: не настолько селективно для Index Scan, но и не настолько много для Seq Scan.

  • Часто встречается при условиях с несколькими индексами (bitmap AND/OR).

Index Only Scan

  • Читает только индекс (heap не трогает), если видимость строк подтверждена (visibility map).

  • Сильно ускоряет read-heavy запросы, но зависит от того, как отрабатывает VACUUM, Autovacuum и bloat.


Что означает cost/rows в EXPLAIN

EXPLAIN показывает оценку, а не факт.

  • cost — относительная “стоимость” узла.
  • первое число: стоимость получить первую строку
  • второе число: стоимость получить все строки узлом

  • rows — ожидаемое число строк на узле (по статистике).

  • Если rows сильно расходится с фактом в EXPLAIN ANALYZE — см. ANALYZE и статистика планировщика.


Типовые причины “плохого” доступа

  • Низкая селективность фильтра ⇒ индекс не помогает.

  • Условие не использует индекс (функции по колонке, не тот оператор, несовместимый тип).

  • Устаревшая статистика ⇒ планировщик неверно оценивает rows.

  • Сильный bloat ⇒ лишние чтения страниц heap/индекса.

См. также: Планировщик запросов и EXPLAIN, Индексы в PostgreSQL, VACUUM, Autovacuum и bloat.

Последнее обновление