- For which data types MongoDB is more suitable.
- Basic tips for optimizing performance.
- How to quickly and easily speed up a high-load project that uses MongoDB as the main data repository.
- How to build queries and use indexes.
2. MongoDB — что это?
MongoDB — это высокопроизводительная документо-
ориентированная база данных без схем данных, которая
относиться к не реляционным БД.
Структура: содержит в себе множество коллекций, они же
содержат множество документов(объектов), которые в свою
очередь содержат пары ключ-значение
3. Документ:
Документ – это набор пар “ключ –
значение”. Документ имеет
динамическую схему.
Документ в одной и той же
коллекции не обязан иметь один
одинаковый набор полей или структуру, а
общие поля в коллекции могут иметь
различные типы данных.
Для хранения MongoDB использует
JSON-подобные документы, который
называется BSON (Binary JSON).
{
field1: value1,
field2: {
embedField1: value,
………………………………..
},
field3: [
value1,
value2, ….
]
}
4. Сравнение с MySQL
MySQL MongoDB
ACID Transactions ACID Transactions
Table Collection
Row Document
Column Field
Index Index
JOINs Embedded documents, $lookup & $graphLookup
GROUP_BY Aggregation Pipeline
5. Когда стоит и использовать MongoDB
У вас нет четкой, заранее описанной структуры данных или
состав данных может потом сильно изменится
У вас планируется довольно серьезный объем данных
Нету большого количества связей между типами данных
У вас приложение с интенсивной записью (удобно для
логирования чего либо)
модно же
6. О чем пойдет речь:
Когда и зачем нужна оптимизация производительности
С чего начать
Как анализировать запросы
Индексы, для чего они нужны
Как правильно строить запросы
7. С чего начать
Смотрим MongoDB Log
по дефолту /var/log/mongodb/mongod.log
Настраиваем и анализируем
Database Profiler
Анализируем запросы
db.collection.explain()
8. Database Profiler
db.setProfilingLevel(level, { slowms: 200 }) - включить
профилирование базы данных
level
0 Профилировщик выключен и не собирает никаких
данных (по умолчанию).
1 Профилировщик собирает данные для операций,
которые занимают больше времени, чем значение
slowms.
2 Профилировщик собирает данные для всех операций.
9. Примеры использования профилировщика
• Получить последние 10 запросов:
db.getCollection('system.profile').limit(10).sort( { ts: -1 } )
• Получить операции, которые выполняются дольше чем 500
миллисекунд:
db.getCollection('system.profile').find({ millis: { $gt: 500 } } )
• Получить наиболеечасто выполняемые запросы:
db.getCollection('system.profile').aggregate([
{ $group: { _id: “$command.query”}, count: { $sum: 1 } }
{ $sort: { count : -1 } }
])
10. Анализируем запросы
db.collection.find({}).explain(‘queryPlanner') - детализирует план,
выбранный оптимизатором запросов.
db.collection.find({}).explain('executionStats') - возвращает
статистику выполнения запроса.
• executionStats.nReturned количество возвращенных документов.
• executionStats.totalKeysExamined: будет 0, если запрос не использует
индекс.
• executionStats.totalDocsExamined: количество отсканированных
документов для получения результата.
11. Indexes
• Single Index
db.records.createIndex( { score: 1 } )
db.records.createIndex( { "location.state": 1 } )
• Compound Index
db.products.createIndex( { "item": 1, "stock": 1 } )
• Text Index
db.reviews.createIndex( { comments: "text" } )
• Unique Single Index
db.members.createIndex( { "user_id": 1 }, { unique: true } )
• Unique Compound Index
db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )
20. Советы
Хранить документы простыми.
Анализ встроенных документов и массивов может быть очень сложным. Кроме того, массивы могут снизить
производительность репликации: при каждом изменении массива все значения массива реплицируются!
Возвращать в запросе только те поля, которые вам нужны.
По возможности не использовать $ne и $nin.
hint() - чтобы заставить MongoDB использовать определенный
индекс
Не забываем про limit() если известно максимальное количество
нужных данных
maxTimeMS() – иногда полезно ограничить время выполнения
запроса
21. Aggregation optimization
Если возможно добавляйте $match + $sort в начало запроса
Всегда используйте последовательность, такую как $match +
$projection, $match1 + $projection1
Ставить $project, $unwind, and $group в конец запроса
Операторы сравнения $lt и $gt вместо $skip для пагинации
Правильная последовательность $sort + $limit +$skip
Если в запросе идут $match + $match один за другим то
объедините их используя $and
Флаг allowDiskUse: true
22. Что дальше
Типов индексов много
Оптимизация на основе архитектуры приложения
Sharding - распределения данных по нескольким
машинам.