CodeRang
Темы SQL

Индексы SQL: EXPLAIN ANALYZE и оптимизация запросов

Индексы SQL помогают ускорять выборки, но сами по себе не гарантируют быстрый запрос. Разберём EXPLAIN ANALYZE, план запроса SQL и условия, при которых PostgreSQL может эффективно использовать составной индекс.

Обновлено · Команда SQL Arena

Что потренируете

  • Читать основные узлы EXPLAIN ANALYZE
  • Различать Seq Scan и Index Scan
  • Подбирать порядок колонок составного индекса
  • Писать sargable-условия
  • Проверять, какие строки и страницы реально читает запрос

Пример задачи в тренажёре

Так выглядит задача в SQL Arena: условие, редактор, результат и схема базы.

Пред.След.Случайная
ЗаданиеОтправкиAI Mentor
Найдите транзакции счёта за май без функции над датой

Для счёта с account_id = 1 получите транзакции за май 2026 года. Верните account_name, created_at и amount. Условие по дате должно оставаться пригодным для работы составного индекса (account_id, created_at): не применяйте функцию к created_at.

Запрос 1PostgreSQLv16
SELECT a.account_name, t.created_at, t.amount
FROM transactions t
JOIN accounts a ON a.id = t.account_id
WHERE t.account_id = 1
  AND t.created_at >= TIMESTAMP '2026-05-01'
  AND t.created_at < TIMESTAMP '2026-06-01'
ORDER BY t.created_at, t.id;
Отправить
Результатaccountstransactions
Ответ принят

Как читать EXPLAIN ANALYZE и использовать индексы SQL

Индекс создан по (account_id, created_at). Первое условие — точное равенство account_id = 1. После него идёт диапазон по created_at. Такой порядок совпадает с логикой запроса: сначала резко ограничивается один счёт, затем внутри его записей выбирается нужный временной диапазон.

Граница месяца записана как created_at >= '2026-05-01' и created_at < '2026-06-01'. Это sargable-условие: колонка остаётся без функции или преобразования, поэтому оптимизатор может рассматривать индексный диапазон. Запись вроде DATE(created_at) BETWEEN ... меняет выражение над колонкой и без подходящего функционального индекса может лишить запрос удобного индексного пути.

EXPLAIN ANALYZE нужен не для поиска слова Index Scan любой ценой. На маленькой таблице PostgreSQL иногда сознательно выбирает Seq Scan, потому что прочитать её целиком дешевле. В реальной задаче сравнивают фактические строки, стоимость, время, количество циклов и объём работы. Оптимизация начинается с плана, а не с предположения, что каждый запрос обязан использовать индекс.

EXPLAIN показывает план, который оптимизатор выбрал для SQL-запроса, а EXPLAIN ANALYZE дополнительно выполняет запрос и показывает фактические показатели выполнения. При чтении плана важно смотреть не только на наличие Index Scan, но и на объём обработанных строк, условия фильтрации и расхождение оценок с фактическими значениями. Для составного индекса важен порядок колонок. Условия также желательно писать так, чтобы индексируемая колонка не была без необходимости обёрнута функцией или преобразованием.

SQLPostgreSQL v16
SELECT a.account_name, t.created_at, t.amount
FROM transactions t
JOIN accounts a ON a.id = t.account_id
WHERE t.account_id = 1
  AND t.created_at >= TIMESTAMP '2026-05-01'
  AND t.created_at < TIMESTAMP '2026-06-01'
ORDER BY t.created_at, t.id;
Результат запроса
account_namecreated_atamount
Northwind2026-05-01 08:30:001400
Northwind2026-05-03 11:15:00900

Ошибки при оптимизации SQL-запросов и индексов

01

Функция применяется к индексируемой колонке

Условие DATE(created_at) = DATE '2026-05-01' выглядит удобно, но оно вычисляет выражение для значения колонки. Для обычного индекса по created_at чаще полезнее записать диапазон от начала дня до начала следующего дня.

02

Составной индекс создаётся в случайном порядке

Индексы (account_id, created_at) и (created_at, account_id) — не одно и то же. Порядок колонок выбирают с учётом реальных условий фильтрации, сортировки и диапазонов. Нельзя просто поставить самой первой колонку с самым понятным названием.

03

Любой Seq Scan считается проблемой

Последовательное чтение небольшой таблицы может быть оптимальным. Даже на большой таблице Seq Scan бывает правильным, если запрос всё равно возвращает значительную её часть. Сначала нужно понять фактический объём работы по EXPLAIN ANALYZE, а уже потом менять запрос или индекс.

Задачи по теме в тренажёре

Курс SQL Performance

Практика оптимизации SQL запросов полезна только тогда, когда приходится принимать решение по плану выполнения. В SQL Arena есть задачи на полный проход журнала, внешний ключ без индекса, выдачу последних заказов и поиск платежей по заказу. На следующем уровне появляются covering index, индексные отчёты и поиск без учёта регистра. Для более последовательной работы есть курс SQL Performance. В нём оптимизация разбирается на базе объёма до 10 млн строк, поэтому разница между полным чтением, индексным доступом и неудачным условием становится заметнее. В интерфейсе доступен EXPLAIN, а решение задачи проходит автопроверку на скрытых данных. Всего SQL Arena содержит 1 192 задачи и отдельные песочницы PostgreSQL, MySQL, ClickHouse и BigQuery.

Частые вопросы

Что такое индексы SQL?

Индекс — дополнительная структура данных, которая помогает СУБД быстрее находить нужные строки для определённых запросов. Индексы ускоряют не все операции и требуют дополнительного места и работы при изменении данных.

Что показывает EXPLAIN ANALYZE?

EXPLAIN ANALYZE выполняет запрос и показывает выбранный план вместе с фактическими показателями выполнения. Это позволяет сравнивать оценки оптимизатора с реально обработанными строками и временем отдельных операций.

Как выполняется оптимизация SQL-запросов?

Сначала нужно определить, где запрос выполняет лишнюю работу: читать план, оценивать количество строк, соединения, сортировки и фильтры. После этого можно менять запрос, индексы или структуру данных и повторно проверять план.

Что такое EXPLAIN SQL?

EXPLAIN показывает предполагаемый план выполнения SQL-запроса без обычного выполнения самого запроса. В PostgreSQL он отображает операции плана, их стоимость и оценки количества строк.

Что такое план запроса SQL?

План запроса — последовательность операций, выбранных оптимизатором для получения результата. В нём могут присутствовать сканирования таблиц и индексов, соединения, сортировки, агрегации и другие операции.

Практика индексов и оптимизации SQL-запросов

Начните с задач на Seq Scan, Index Scan и простые индексы, затем переходите к составным и покрывающим индексам. Для углублённой практики продолжите в курсе SQL Performance.

Практиковать оптимизацию SQL