lesson ── postgres-labs ── ~25 мин ── 5 шагов
Меняя только границу в WHERE, проведём один запрос через все методы
доступа: Seq Scan на широком условии, Index/Bitmap на узком, Index-Only
Scan, когда таблицу можно не трогать. Запусти psql во вкладке client.
интерактивный sandbox
Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.
stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя
CREATE TABLE big AS SELECT g AS id, (g % 1000) AS k FROM generate_series(1, 200000) g;
CREATE INDEX ON big(k);
ANALYZE big;
200 тысяч строк хватит, чтобы планы стали реалистичными.
✓ Таблица и индекс готовы.
EXPLAIN SELECT * FROM big WHERE k = 7;
Мало строк - планировщик берёт индекс (Index Scan или Bitmap Index Scan). Предскажи тип перед проверкой.
При малой доле строк индекс дешевле полного прохода.
✓ Узкое условие ушло в индексный доступ.
EXPLAIN SELECT * FROM big WHERE k < 900;
Почти вся таблица - индекс невыгоден, планировщик читает всё подряд.
Когда нужна большая доля строк, Seq Scan дешевле случайных обращений.
✓ Широкое условие - Seq Scan, как и ожидалось.
Просим только проиндексированную колонку - в таблицу за данными идти не надо, всё есть в индексе:
EXPLAIN SELECT k FROM big WHERE k = 7;
План использует индекс. Но чистого Index-Only Scan пока нет: visibility map не выставлена, поэтому планировщик не уверен, что строки видны всем, и берёт обычный индексный доступ. Предскажи тип узла перед проверкой.
Без visibility map планировщик не выбирает Index-Only Scan - индекс используется, но обычный.
✓ Запрос покрыт индексом; до VACUUM это ещё не Index-Only Scan.
VACUUM big;
EXPLAIN ANALYZE SELECT k FROM big WHERE k = 7;
После VACUUM visibility map выставлена, и план становится Index Only Scan с Heap Fetches: 0 - в таблицу больше не ходим.
Индекс не хранит видимость; её подтверждает visibility map, которую ставит VACUUM.
✓ Heap Fetches: 0 - Index-Only Scan работает в полную силу.
Четыре метода доступа выбираются по селективности: Seq Scan (большая доля), Index/Bitmap Scan (малая и средняя), Index-Only Scan (все колонки в индексе). Index-Only Scan проверяет видимость через visibility map; пока VACUUM её не выставил, видны Heap Fetches.
команды
EXPLAIN SELECT * FROM t WHERE c = 7;посмотреть метод доступаVACUUM t;выставить visibility map - убрать Heap Fetchesконцепции