Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
Рейтинг: 34.2% · 2 голосов
Войдите, чтобы голосовать
Голосовать «За» и «Против» могут только авторизованные пользователи. Войдите в свой аккаунт — или зарегистрируйтесь, это займёт минуту.
Нет аккаунта? Зарегистрироваться
Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
Таблица orders, 80 млн строк, 60 ГБ. Есть индекс по (status, created_at). Запрос вида select ... where status = 'pending' and created_at > now() - interval '1 day' возвращает примерно 20 тысяч строк, а планировщик лепит parallel seq scan на 50 секунд. Если сделать set enable_seqscan = off, идет по индексу за 300 мс. ANALYZE гонял, default_statistics_target поднимал до 500, не помогло. Сервер: NVMe, 32 ГБ RAM, конфиг почти дефолтный, random_page_cost не трогал. Куда копать?
✔ Лучший ответ сформирован автоматически — grumpylurker
tonyray писал(а):На NVMe ставь 1.1, и 90 процентов таких загадок исчезает только не надо 1.1 лепить вообще везде, как тут любят советовать. если база в облаке на сетевых дисках, реальная цена случайного чтения сильно выше нвмешной, и с 1.1 планировщик радостно начнет лупить nested loop по индексам там, где hash join отрабатывал за секунды. у ОП железный сервер с нвме, ему да, ставить смело
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
random_page_cost не трогал, вот и весь ответ. Дефолтная четверка это про шпиндельные диски из 2005 года. На NVMe ставь 1.1, и 90 процентов таких загадок исчезает, планировщик просто перестает бояться случайного чтения. Заодно подними effective_cache_size до 24 ГБ, чтобы он знал, что у тебя есть кеш ОС.
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
почти дефолтный конфиг на проде с 80 млн строк это конечно сильно. shared_buffers небось тоже 128 мб стоят? сначала базовый тюнинг по памяти и стоимостям, потом удивляться планам. pgtune хотя бы прогони, две минуты дела
- lonelygoblin
- Сообщения: 61
- Зарегистрирован: 12 май 2026, 12:45
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
Без explain (analyze, buffers) обоих вариантов это гадание на кофейной гуще. И посмотри pg_stats по колонке status, поле most_common_vals. Если pending по статистике занимает половину таблицы, планировщик честно считает, что индекс не окупится, и формально он прав. Тогда тебе нужен частичный индекс where status = 'pending', он и меньше будет раз в десять.
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
ставил random_page_cost 1.1 на трех проектах, ни разу не пожалел. на одном из них верхушка pg_stat_statements ускорилась раз в 40 без единого нового индекса. до сих пор не понимаю, почему в 2026 это все еще не дефолт
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
@Kutz, а 50 секунд это из приложения или из psql? классическая ловушка: драйвер заворачивает запрос в prepared statement, после пятого выполнения постгрес уходит на generic plan, а там селективность по status усредненная и seq scan внезапно дешевле. в psql при этом все летает, и ты неделю ловишь призрака. проверь через prepare/execute с explain или поставь plan_cache_mode = force_custom_plan и сравни
- grumpylurker
- Сообщения: 63
- Зарегистрирован: 15 май 2026, 01:41
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
✔ Лучший ответ — сформирован автоматически
только не надо 1.1 лепить вообще везде, как тут любят советовать. если база в облаке на сетевых дисках, реальная цена случайного чтения сильно выше нвмешной, и с 1.1 планировщик радостно начнет лупить nested loop по индексам там, где hash join отрабатывал за секунды. у ОП железный сервер с нвме, ему да, ставить смелоtonyray писал(а):На NVMe ставь 1.1, и 90 процентов таких загадок исчезает
Re: Postgres 17 упорно выбирает seq scan вместо индекса, таблица 80 млн строк
еще вариант, который никто не назвал: расширенная статистика. create statistics с dependencies по (status, created_at), потом analyze. если pending это почти всегда свежие строки, планировщик считает условия независимыми, перемножает селективности и оценка уезжает в разы. у меня на похожей orders-таблице была оценка 2 млн строк вместо реальных 30к, после dependencies одумался сам, без кручения random_page_cost
Поделиться темой:
✈ Telegram
VK
- Похожие темы
-
- Внедрили ClickHouse, а Postgres всё равно никуда не делся. Так и должно быть?
20 ответов · 1698 просмотров
-
- Autovacuum не успевает, bloat растёт, таблица 200ГБ а живых данных 30. Кто как тюнит?
11 ответов · 1235 просмотров
-
-
-
- Решил кэшировать прямо в Postgres вместо Redis, чтобы не плодить зависимости. Норм идея?
3 ответов · 248 просмотров
-
Кто сейчас на конференции
Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей