MongoDB
Как оптимизировать MongoDB
MongoDB оптимизируют не абстрактно, а от конкретного медленного запроса. Сначала найдите запрос, затем посмотрите explain("executionStats"), после этого добавляйте индекс, меняйте сортировку, projection или структуру данных. Без измерения легко создать лишние индексы и не исправить реальную проблему
Пример проверки:
db.products.find({
category: "hoodies",
active: true
}).sort({ price: -1 }).explain("executionStats")
Смотрите, сколько документов просмотрено и сколько вернулось
Индекс под фильтр и сортировку
Если запрос часто фильтрует по category, active и сортирует по price, можно создать составной индекс:
db.products.createIndex({
active: 1,
category: 1,
price: -1
})
После этого снова выполните explain и сравните результат. Хороший признак — MongoDB просматривает меньше документов
Уменьшите результат
Не вытаскивайте все поля, если нужны только название и цена:
db.products.find(
{ active: true },
{ title: 1, price: 1, _id: 0 }
)
Projection особенно полезен, если документы большие: описания, изображения, настройки, вложенные массивы
Ограничьте выдачу
Для интерфейса обычно не нужны тысячи документов сразу:
db.products
.find({ active: true })
.sort({ createdAt: -1 })
.limit(20)
Добавьте пагинацию или курсорную навигацию, если список большой
Проверьте модель данных
Иногда проблема не в индексе, а в структуре. Если каждый экран собирается через тяжелую агрегацию, возможно, часть данных стоит хранить ближе к документу, который читается чаще. Если документ содержит огромный массив, возможно, этот массив нужно вынести в отдельную коллекцию
Проверьте медленные места приложения
Оптимизация базы начинается с измерений в приложении. Запишите, какой endpoint тормозит, какой запрос он выполняет и сколько документов возвращает. Часто оказывается, что база работает нормально, а приложение просто запрашивает слишком много данных или делает один запрос в цикле для каждого элемента списка
Простой чек-лист:
- есть ли
limit; - есть ли projection;
- есть ли индекс под фильтр;
- не выполняется ли запрос внутри цикла;
- не загружается ли большой массив без необходимости.
Агрегации тоже нужно проверять
Если используется aggregate, смотрите план выполнения и старайтесь ставить $match как можно раньше, чтобы следующие стадии работали с меньшим числом документов. Не начинайте pipeline с тяжелой обработки всей коллекции, если можно сначала отфильтровать нужные записи
Частые ошибки
Создают индекс на каждое поле
Индексы ускоряют чтение, но замедляют запись и занимают место. Создавайте индексы под реальные запросы
Сортируют без индекса
Сортировка по большому набору документов без индекса может быть дорогой
Не используют explain
Без explain оптимизация превращается в догадки
Загружают слишком много данных
Используйте projection, limit и пагинацию
Оптимизируют не тот запрос
Сначала найдите реальный медленный запрос, потом меняйте индекс или модель. Иначе можно улучшить то, чем пользователь почти не пользуется
Как проверить улучшение
Сохраните показатели до и после: время запроса, количество просмотренных документов, используемый индекс. Если после индекса запрос стал быстрее и просматривает меньше документов, оптимизация сработала
Что почитать дальше по MongoDB
Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:
- Discord bot на Python и MongoDB: как задать проверку
- Failed to start MongoDB database server: что проверить
- MongoDB Atlas: облачная база для первого проекта
- MongoDB Compass: подключение и первая коллекция без командной строки