0Pricing
SQL Academy · Урок

Последовательное сканирование и сканирование по индексу

Узнайте, когда достаточно последовательного сканирования, когда требуется сканирование по индексу и как это определяет планировщик

«Последовательное сканирование и сканирование по индексу» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Чтение EXPLAIN и EXPLAIN ANALYZE
  2. Последовательное сканирование и сканирование по индексу
  3. Хеш-соединение, соединение слиянием и вложенный цикл
  4. Поиск и исправление медленных запросов
← Назад к SQL Academy