Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Теги: #PostgreSQL
Рейтинг: 39% · 56 голосов
SQL и NoSQL: PostgreSQL, MySQL, Redis, MongoDB, ClickHouse, ElasticSearch — проектирование схем, индексы, репликация и оптимизация запросов.
Аватара пользователя
cohenst1
Сообщения: 92
Зарегистрирован: 11 май 2026, 02:08

Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение cohenst1 »

PostgreSQL 16, таблица orders ~12 млн строк, делаю JOIN с users по user_id и фильтр по created_at за последний месяц. Запрос 5 секунд. В EXPLAIN вижу Seq Scan на orders, хотя индекс на created_at есть. Почему не используется?
👍 ❤️ 🔥 😄 🤔
✔ Лучший ответ сформирован автоматически — rust_sre
@qcdeed, covering index хорошая идея, но стоит уточнить: index-only scan сработает только если visibility map актуальна, то есть VACUUM прошёл по страницам достаточно недавно. На горячей таблице с частыми обновлениями visibility map может быть грязной, и Postgres всё равно будет лазить в heap за видимостью. Можно проверить через pg_stat_user_tables: колонка n_live_tup vs heap_blks_hit после…
Перейти к ответу →
Аватара пользователя
qawsqaws
Сообщения: 11
Зарегистрирован: 11 май 2026, 17:11

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение qawsqaws »

Скинь полный EXPLAIN ANALYZE, а не просто план. Без него гадаем. Но навскидку: если фильтр выбирает большую долю таблицы, планировщик сознательно выберет seq scan, это нормально.
👍4 ❤️1 🔥2 😄1 🤔
Аватара пользователя
asynclover
Сообщения: 70
Зарегистрирован: 13 май 2026, 04:35

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение asynclover »

За месяц это примерно 1.5 млн строк из 12 млн. То есть 12%.
👍 ❤️ 🔥1 😄1 🤔
Аватара пользователя
qcdeed
Сообщения: 57
Зарегистрирован: 11 май 2026, 20:16

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение qcdeed »

Вот и ответ. 12% — это уже та зона где seq scan часто выгоднее random access по индексу. Попробуй covering index: CREATE INDEX ON orders (created_at) INCLUDE (user_id, amount), тогда index-only scan может выстрелить.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
jbosco
Сообщения: 60
Зарегистрирован: 11 май 2026, 02:28

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение jbosco »

Плюс проверь когда последний раз бегал ANALYZE по таблице. Кривая статистика — причина половины подобных кейсов. И посмотри на work_mem, если идёт hash join с диском на temp, оно само по себе даст секунды.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
ansiblemain
Сообщения: 4
Зарегистрирован: 12 май 2026, 14:00

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение ansiblemain »

Ещё классика: created_at у тебя точно timestamp, а не timestamptz, и в запросе нет неявного приведения типов? Каст по колонке убивает индекс моментально.
👍3 ❤️ 🔥1 😄1 🤔
Аватара пользователя
FpgaDev
Сообщения: 43
Зарегистрирован: 12 май 2026, 04:40

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение FpgaDev »

О, work_mem стоит дефолтные 4MB. Поднял до 64MB на сессию — запрос упал до 800мс. Hash join перестал уходить на диск. Спасибо, не думал что так сильно влияет!
👍 ❤️ 🔥 😄 🤔1
Аватара пользователя
RedisNinja
Сообщения: 61
Зарегистрирован: 15 май 2026, 01:22

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение RedisNinja »

Вот-вот. Дефолтный work_mem 4MB — это наследие времён когда сервера были с 1GB RAM. Но не ставь его глобально в гигабайты, он же на каждую операцию сортировки, прибьёшь память при конкурентных запросах.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
rust_sre
Сообщения: 16
Зарегистрирован: 15 май 2026, 23:32

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение rust_sre »

✔ Лучший ответ — сформирован автоматически
@qcdeed, covering index хорошая идея, но стоит уточнить: index-only scan сработает только если visibility map актуальна, то есть VACUUM прошёл по страницам достаточно недавно. На горячей таблице с частыми обновлениями visibility map может быть грязной, и Postgres всё равно будет лазить в heap за видимостью. Можно проверить через pg_stat_user_tables: колонка n_live_tup vs heap_blks_hit после создания индекса покажет, используется ли он реально без heap.
👍3 ❤️ 🔥 😄 🤔
Аватара пользователя
jpearce
Сообщения: 47
Зарегистрирован: 11 май 2026, 23:34

Re: Запрос с JOIN тормозит на 5 секунд, EXPLAIN внутри — помогите разобраться

Сообщение jpearce »

@FpgaDev, с work_mem важно не забыть: SET work_mem = '64MB' на сессию — это нормально для отладки, но если поднять глобально, то при 100 одновременных коннектах с несколькими операциями сортировки каждый это 100 * несколько * 64MB. На боевом сервере лучше либо выставлять в BEGIN...COMMIT для конкретных тяжёлых запросов, либо использовать параметр на уровне роли/пользователя для аналитических запросов, а не на всём инстансе.
👍3 ❤️1 🔥 😄1 🤔
Ответить
Поделиться темой: ✈ Telegram VK
Похожие запросы: оконные функции postgresql примеры over partition byкак читать план запроса explain analyze в postgresqlstrace почему программа висит и тормозиткак посмотреть процессы в linux и убить зависшийс чего начать диагностику linux когда сервер тормозит

Вернуться в «Базы данных»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость