Почему PostgreSQL игнорирует индексы

Вопрос: почему планировщик PostgreSQL игнорирует корректно созданные индексы в пользу Sequential Scan?

Линия поддержки
Линия поддержки Ответы на вопросы пользователей
26 июня 2026

Что делать, если индексы в PostgreSQL созданы корректно, но точечные запросы всё равно зависают на Sequential Scan?

Изображение записи

Комментарий пользователя

Мы создали все необходимые индексы для таблицы, но PostgreSQL упорно их игнорирует. При выполнении точечного запроса планировщик почему-то все равно выбирает полное сканирование диска (Sequential Scan), из-за чего выборка зависает. Почему база данных не видит созданные индексы?

Андрей Юдин Пользователь

Ответ специалиста

Добрый день, Андрей! Дело в том, что наличие индекса в базе данных не гарантирует, что оптимизатор выберет именно его. PostgreSQL строит план выполнения на основе внутренней модели затрат и выбирает тот путь, который по расчетам выглядит дешевле. Если индексы созданы корректно, но СУБД переходит к полному последовательному сканированию таблицы (Seq Scan), это может происходить по нескольким причинам.

Устаревшая или неполная статистика

Планировщик оценивает стоимость запроса на основе статистических данных: количества строк, числа страниц на диске и распределения значений в колонках. Если вы недавно импортировали, реплицировали, массово добавили или удалили большой объем данных, статистика становится неактуальной. База данных строит неверные предположения о количестве строк, занижает стоимость последовательного чтения и игнорирует индекс.

Для исправления ситуации нужно обновить статистику для таблицы вручную, чтобы оптимизатор увидел реальное распределение данных:

  • Александр Гришин

    Александр Гришин

    Руководитель по развитию продуктов хранения данных


      ANALYZE users;

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


      VACUUM ANALYZE users;

Несоответствие типов данных или функций

Индекс B-Tree может игнорироваться, если в условии WHERE тип передаваемого параметра не совпадает с типом колонки в базе (происходит неявное приведение типов), либо если поле обернуто в функцию, под которую не был создан специальный индекс.

Чтобы проверить работу планировщика, запустите запрос с командой проверки реального плана:


      EXPLAIN ANALYZE
SELECT id, name FROM users WHERE email = 'admin@example.com';

Затем сравните показатели в выводе:

  • rows в блоке оценки стоимости — сколько строк планировщик ожидал найти.
  • rows в блоке Actual time — сколько строк было получено на самом деле.

Если эти значения сильно различаются (например, ожидалась 1 строка, а обработано 100 000), это прямое подтверждение того, что статистика устарела. После выполнения команды ANALYZE планировщик пересчитает cost и автоматически переключится на быстрый Index Scan.

Больше про оптимизацию PostgreSQL читайте в нашем материале.