Последовательное сканирование и сканирование по индексу
Узнайте, когда достаточно последовательного сканирования, когда требуется сканирование по индексу и как это определяет планировщик
«Последовательное сканирование и сканирование по индексу» — бесплатный урок SQL Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.
Два способа найти строки
У базы данных есть две основные стратегии чтения строк:
- Последовательное сканирование — прочитать каждую страницу таблицы
- Сканирование по индексу — пройти индекс и получить подходящие строки
Когда последовательное сканирование подходит
Если вам в любом случае нужна большая часть таблицы, сканирование дешевле, чем чтение индекса AND получение каждой подходящей строки. В целом: при количестве строк свыше примерно 10–20 % → последовательное сканирование выгоднее.
Когда сканирование по индексу выигрывает
Для селективных запросов (для небольшой доли строк) индекс окупается:
EXPLAIN SELECT * FROM users WHERE id = 42;
-- Index Scan using users_pkey (cost=0.43..8.45 rows=1)
EXPLAIN SELECT * FROM users WHERE active;
-- Seq Scan on users (cost=0.00..15000.00 rows=950000)
-- (because most users are active)Сканирование по индексу и сканирование только по индексу
Иногда в самом индексе есть все необходимые столбцы — получать данные из таблицы не нужно. Это сканирование только по индексу:
CREATE INDEX users_email_id_idx ON users(id) INCLUDE (email);
EXPLAIN SELECT email FROM users WHERE id = 42;
-- Index Only Scan using users_email_id_idxСканирование индекса по битовой карте
При средней селективности PostgreSQL может построить битовую карту подходящих строк, а затем получить их в физическом порядке — это быстрее произвольного ввода-вывода:
EXPLAIN SELECT * FROM orders WHERE status = 'pending';
-- Bitmap Heap Scan on orders
-- Recheck Cond: (status = 'pending')
-- -> Bitmap Index Scan on orders_status_idxПочему планировщик выбирает последовательное сканирование
Распространённые причины:
- Нет индекса для столбца, по которому выполняется фильтрация
- Индекс нельзя использовать (функция над столбцом, предложения OR, несовпадение типов)
- Ожидаемое число строк слишком велико, чтобы индекс был выгоден
- Статистика устарела, и планировщик неправильно оценивает селективность
Принудительное использование индекса (с осторожностью)
Нельзя напрямую задавать подсказки для PostgreSQL. Вместо этого:
- Выполните ANALYZE, чтобы обновить статистику
- Добавьте подходящий индекс
- Задайте параметры сеанса:
SET enable_seqscan = off;для диагностики (не в рабочей среде)
Индексируемые предикаты
Чтобы индекс помог, условие WHERE должно быть «пригодным для использования индекса» — индексированный столбец нужно сравнивать напрямую:
-- GOOD:
WHERE created_at >= '2024-01-01'
-- BAD (function on the column):
WHERE date_trunc('day', created_at) = '2024-01-01'
-- BAD (cast):
WHERE created_at::DATE = '2024-01-01'
-- FIX: add a functional index, or rewrite with range.Порядок столбцов составного индекса
Индекс по (a, b) помогает запросам только по a и по a AND b, но не только по b.
Размер индекса имеет значение
Узкий индекс B-дерева с часто используемыми ключами может полностью помещаться в памяти; широкий индекс — нет. Меньшие индексы работают быстрее.
Проверьте план
После добавления индекса запустите EXPLAIN ANALYZE, чтобы убедиться, что планировщик действительно его использует. Если нет, разберитесь глубже.
Итоги
Выбор между последовательным сканированием и сканированием по индексу определяется селективностью.
- Селективный фильтр → сканирование по индексу
- Большая часть таблицы → последовательное сканирование
- Для промежуточного случая — сканирование по битовой карте
- Следите за пригодностью условий для использования индекса
Быстрая проверка
Почему PostgreSQL может выбрать последовательное сканирование вместо существующего индекса?
Часто задаваемые вопросы
Урок «Последовательное сканирование и сканирование по индексу» бесплатный?
Да — полный текст урока «Последовательное сканирование и сканирование по индексу» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.
Чему я научусь в уроке «Последовательное сканирование и сканирование по индексу»?
Узнайте, когда достаточно последовательного сканирования, когда требуется сканирование по индексу и как это определяет планировщик Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Academy?
Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Последовательное сканирование и сканирование по индексу»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Academy?
Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Чтение EXPLAIN и EXPLAIN ANALYZE
- Последовательное сканирование и сканирование по индексу
- Хеш-соединение, соединение слиянием и вложенный цикл
- Поиск и исправление медленных запросов