MongoDB медленные запросы как найти и оптимизировать

Рейтинг: 70.3% · 30 голосов
SQL и NoSQL: PostgreSQL, MySQL, Redis, MongoDB, ClickHouse, ElasticSearch — проектирование схем, индексы, репликация и оптимизация запросов.
Ответить
Аватара пользователя
tomcruz
Сообщения: 29
Зарегистрирован: 12 май 2026, 18:25

MongoDB медленные запросы как найти и оптимизировать

Сообщение tomcruz »

Приложение на MongoDB 6.0 начало тормозить под нагрузкой. Коллекция events около 80 млн документов. Запросы по полям userId + createdAt иногда выполняются секундами. Как найти проблемные запросы и понять что именно тормозит?
👍1 ❤️2 🔥 😄 🤔
✔ Лучший ответ выбран автором и совпадает с автоматическим подбором — k8s2000
Подробно про индексную стратегию для вашего случая: правило ESR (Equality, Sort, Range) — сначала поля по которым делаешь точное равенство (userId =), потом поля сортировки (createdAt), потом поля диапазонов. Для запросов вида find({userId: X, createdAt: {$gte: Y}}).sort({createdAt: -1}) оптимальный индекс {userId: 1, createdAt: -1}. Также проверь через db.events.stats() и…
Перейти к ответу →
Аватара пользователя
k_egor_s
Сообщения: 20
Зарегистрирован: 16 май 2026, 11:11

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение k_egor_s »

Первым делом включи профилировщик MongoDB: db.setProfilingLevel(1, { slowms: 100 }) — это запишет в system.profile все запросы медленнее 100мс. Потом смотри db.system.profile.find().sort({millis:-1}).limit(10) — найдёшь самых злодеев. Ищи поле docsExamined: если оно в разы больше nReturned — индекс либо отсутствует, либо неэффективен.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
jbosco
Сообщения: 60
Зарегистрирован: 11 май 2026, 02:28

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение jbosco »

На 80 млн документов составной индекс обязателен. Создай db.events.createIndex({userId: 1, createdAt: -1}) — порядок полей важен. Если запросы всегда фильтруют по userId и сортируют по createdAt desc — именно такой индекс покроет оба условия и избежит in-memory sort.
👍4 ❤️2 🔥2 😄2 🤔
Аватара пользователя
k8spro
Сообщения: 1
Зарегистрирован: 15 май 2026, 12:02

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение k8spro »

explain() твой лучший друг. db.events.find({userId: 'xxx'}).sort({createdAt: -1}).explain('executionStats') покажет: используется ли индекс (IXSCAN vs COLLSCAN), сколько документов просканировано, есть ли этап SORT в памяти. Если видишь totalDocsExamined >> nReturned или стадию SORT — есть что оптимизировать.
👍2 ❤️1 🔥 😄1 🤔
Аватара пользователя
k8s2000
Сообщения: 85
Зарегистрирован: 11 май 2026, 00:27

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение k8s2000 »

✔ Лучший ответ — выбран автором и совпадает с авто-подбором
Подробно про индексную стратегию для вашего случая: правило ESR (Equality, Sort, Range) — сначала поля по которым делаешь точное равенство (userId =), потом поля сортировки (createdAt), потом поля диапазонов. Для запросов вида find({userId: X, createdAt: {$gte: Y}}).sort({createdAt: -1}) оптимальный индекс {userId: 1, createdAt: -1}. Также проверь через db.events.stats() и db.events.totalIndexSize() — если индексы не влезают в RAM (wiredTiger кэшируется через parameter storage.wiredTiger.engineConfig.cacheSizeGB, по умолчанию 50% RAM), то производительность деградирует из-за постоянных page fault. Ещё: если поле createdAt типа string а не Date — сортировка будет лексикографической и индекс не поможет как ожидается. Всегда храни даты как Date.
👍1 ❤️ 🔥 😄1 🤔
Аватара пользователя
gowizard
Сообщения: 16
Зарегистрирован: 13 май 2026, 19:47

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение gowizard »

Mongostat и mongotop запускай во время нагрузки — mongostat покажет количество операций в секунду, page faults, очереди на чтение/запись. Если qr|qw растут — это признак нехватки ресурсов или локов.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
Sjobs
Сообщения: 27
Зарегистрирован: 15 май 2026, 07:40

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение Sjobs »

Кстати, для аналитики по events с фильтрами за большие диапазоны дат MongoDB не самый лучший выбор. Если это логи или события — посмотри на ClickHouse или TimescaleDB, они для таких сценариев значительно быстрее.
👍1 ❤️ 🔥 😄 🤔1
Аватара пользователя
hhhhhhhhh
Сообщения: 7
Зарегистрирован: 16 май 2026, 02:39

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение hhhhhhhhh »

К сказанному добавлю две вещи, о которых обычно вспоминают поздно. Первое: на 80 млн документов само построение индекса нагрузит прод — в 6.0 билды уже не блокирующие, но IO жрут прилично, запускай в окно минимальной нагрузки, а на реплика-сете лучше rolling build по нодам. Второе: проверь, влезают ли индексы в WiredTiger cache (по умолчанию ~50% RAM) — сравни db.events.totalIndexSize() с размером кэша. Если индексы не помещаются в память, никакой IXSCAN не спасёт, будешь читать индекс с диска. И если старые события не нужны — TTL-индекс по createdAt, коллекция хотя бы перестанет пухнуть.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
Version
Сообщения: 68
Зарегистрирован: 11 май 2026, 03:17

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение Version »

@k8spro, дополню по explain: кроме executionStats стоит смотреть allPlansExecution — бывает, что планер выбирает не тот индекс из нескольких похожих, и запрос тормозит при формально существующем правильном индексе. У нас так было с {userId:1, createdAt:-1} и старым {userId:1, status:1}: планер закэшировал план под второй, и до чистки через db.events.getPlanCache().clear() запросы упорно шли мимо нужного индекса.
👍3 ❤️ 🔥 😄1 🤔
Аватара пользователя
juniorredteam
Сообщения: 66
Зарегистрирован: 11 май 2026, 07:16

Re: MongoDB медленные запросы как найти и оптимизировать

Сообщение juniorredteam »

@Sjobs, смотря какой паттерн запросов. Если основной кейс — «покажи последние события юзера» для UI, Mongo с индексом {userId, createdAt} отрабатывает за миллисекунды, и тащить ClickHouse ради этого — лишняя сущность в проде плюс второй пайплайн доставки данных. ClickHouse оправдан, когда пошла настоящая аналитика: агрегации за месяцы по всем юзерам сразу. Я бы сначала починил индексы, а уже потом, если останутся тяжёлые аналитические запросы, выносил их отдельно — не наоборот.
👍1 ❤️1 🔥3 😄 🤔
Ответить
Поделиться темой: ✈ Telegram VK
Похожие запросы: почему postgresql медленный и как ускоритьстоит ли становиться айтишником

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

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

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