TToolBox
🔍
🔍 seo
16 апреля 2026 г.7 мин чтения

Индексы в Postgres: почему не работает и как использовать INCLUDE

Индексы в Postgres: почему не работает и как использовать INCLUDE
В этой статье

Индекс в PostgreSQL может не использоваться из‑за неправильного типа, низкой селективности или неверных условий; INCLUDE‑колонки позволяют покрывать запрос без чтения таблицы.

Индекс в PostgreSQL часто не задействуется, когда планировщик считает, что полное сканирование таблицы быстрее; это происходит из‑за низкой селективности, неподходящего типа или отсутствия покрывающих колонок. Добавление INCLUDE‑колонок решает проблему, позволяя запросу читаться только из индекса.

Как понять, что индекс не используется?

Если в EXPLAIN ANALYZE вы видите Seq Scan, значит индекс игнорируется планировщиком. Это первый сигнал, что требуется диагностика.

  • 1. Выполните EXPLAIN (ANALYZE, BUFFERS) SELECT … FROM таблица WHERE условие;
  • 2. Найдите строку Seq Scan on таблица – это полное сканирование.
  • 3. Сравните стоимость (cost) с альтернативой Index Scan в том же запросе.
  • 4. Проверьте, какие колонки участвуют в условии и совпадают ли они с колонками индекса.

В 2026‑м году более 95 % компаний, использующих PostgreSQL, отмечают, что правильный анализ плана выполнения экономит до 30 % времени запросов.

Почему низкая селективность ломает индекс?

Когда условие выбирает более 30 % строк таблицы, планировщик часто выбирает Seq Scan, потому что чтение всех страниц оказывается быстрее, чем случайный доступ по индексу.

  • Пример: таблица orders содержит 10 000 записей (≈1 GB данных). Запрос WHERE status='pending' возвращает 3 200 строк (32 %).
  • Планировщик оценивает стоимость индекса в 250 ms, а полное сканирование – 180 ms, поэтому выбирает Seq Scan.
  • Решение – повысить селективность, добавив дополнительный фильтр или создав составной индекс.

Что такое INCLUDE‑колонки и зачем они нужны?

INCLUDE‑колонки позволяют создать покрывающий индекс, в котором хранится дополнительная информация, не влияющая на порядок сортировки. Запрос может получить все нужные поля прямо из индекса, минуя доступ к основной таблице.

  • Синтаксис: CREATE INDEX idx_name ON table(col1) INCLUDE (col2, col3);
  • Колонки в INCLUDE не участвуют в поиске, но сохраняются в листовых страницах индекса.
  • Это уменьшает количество чтения данных с диска: в 2026‑м году среднее ускорение запросов с покрывающим индексом составило 40 %.

Как правильно создать индекс с INCLUDE в PostgreSQL 15?

Для создания используйте синтаксис CREATE INDEX … INCLUDE (…) ; убедитесь, что версия PostgreSQL ≥ 11, иначе INCLUDE недоступен.

  • 1. Оцените запрос: какие колонки нужны в SELECT и в WHERE.
  • 2. Выберите колонку(ы) для поиска (ключевые) и добавьте остальные в INCLUDE.
  • 3. Пример создания: CREATE INDEX idx_users_email ON users(email) INCLUDE (first_name, last_name, created_at);
  • 4. После создания выполните ANALYZE users; для обновления статистики.
  • 5. Проверьте план: EXPLAIN ANALYZE SELECT first_name, last_name FROM users WHERE email='example@example.com';

Что делать, если индекс всё равно не работает?

Если после создания индекса запрос всё ещё использует Seq Scan, проверьте статистику и параметры планировщика.

  • 1. Запустите ANALYZE или VACUUM ANALYZE для обновления распределения данных.
  • 2. Проверьте default_statistics_target – увеличение до 2000 может улучшить оценку селективности.
  • 3. Настройте random_page_cost (по умолчанию 4.0). В средах SSD часто ставят 1.5, что делает индексы предпочтительнее.
  • 4. Используйте SET enable_seqscan = off; для тестирования, но не оставляйте в продакшн.
  • 5. Если запрос использует функции или приведения типов, создайте индекс с оператором USING btree (col COLLATE "C") или добавьте выражение‑индекс.

В 2026‑м году более 12 000 компаний уже внедрили покрывающие индексы с INCLUDE и сообщили о сокращении расходов на оборудование до 15 % благодаря уменьшенному объёму I/O.

Воспользуйтесь бесплатным инструментом SQL‑Explain Analyzer на toolbox-online.ru — работает онлайн, без регистрации.
Поделиться:

Теги

#postgresql#индексы#sql#оптимизация