Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Немного о оптимизации
производительности
Грига Иван
Backend developer в компании Smart Gamma
MongoDB — что это?
MongoDB — это высокопроизводительная документо-
ориентированная база данных без схем данных, которая
от...
Документ:
Документ – это набор пар “ключ –
значение”. Документ имеет
динамическую схему.
Документ в одной и той же
коллекц...
Сравнение с MySQL
MySQL MongoDB
ACID Transactions ACID Transactions
Table Collection
Row Document
Column Field
Index Index...
Когда стоит и использовать MongoDB
У вас нет четкой, заранее описанной структуры данных или
состав данных может потом сил...
О чем пойдет речь:
Когда и зачем нужна оптимизация производительности
С чего начать
Как анализировать запросы
Индексы,...
С чего начать
Смотрим MongoDB Log
по дефолту /var/log/mongodb/mongod.log
Настраиваем и анализируем
Database Profiler
Ан...
Database Profiler
db.setProfilingLevel(level, { slowms: 200 }) - включить
профилирование базы данных
level
0 Профилировщик...
Примеры использования профилировщика
• Получить последние 10 запросов:
db.getCollection('system.profile').limit(10).sort( ...
Анализируем запросы
db.collection.find({}).explain(‘queryPlanner') - детализирует план,
выбранный оптимизатором запросов.
...
Indexes
• Single Index
db.records.createIndex( { score: 1 } )
db.records.createIndex( { "location.state": 1 } )
• Compound...
Compound Index и сортировка
N# Query Index
1 db.data.find().sort({a: 1, b: -1}) {a: 1, b: -1}
2 db.data.find().sort({a: -1...
Примеры. Структура документов коллекции
{
fname: string,
isHidden: boolean,
………………………………………………………………..
messages: [
{
dataI...
Пример 1
db.getCollection.find({"fname": "Maxwell", "isHidden": { "$ne": true }, "messages.status": "delivered“}).sort({ "...
Пример 2
После создания индексов ничего не изменилось.
db.getCollection.aggregate([
{ "$unwind": "$messages" },
{
"$match"...
$unwind
При агрегации данных $unwind позволяем развернуть поля-
подмассивы путём дублирования в выборке родительской
сущн...
Выполнение 3 523 миллисекунды Выполнение 204 миллисекунды
db.getCollection.aggregate([
{ "$unwind": "$messages" },
{
"$mat...
$project
Передает документы с запрошенными полями к следующему
этапу агрегации. Указанные поля могут быть существующими
п...
Пример 3. Пагинация.
• Выполнение 15.4 секунды
db.getCollection.aggregate([
{ "$match": {gender: "Male"} },
{ "$sort": {"_...
Советы
Хранить документы простыми.
Анализ встроенных документов и массивов может быть очень сложным. Кроме того, массивы ...
Aggregation optimization
Если возможно добавляйте $match + $sort в начало запроса
Всегда используйте последовательность,...
Что дальше
Типов индексов много
Оптимизация на основе архитектуры приложения
Sharding - распределения данных по несколь...
Спасибо за внимание
Вопросы?
Nächste SlideShare
Wird geladen in …5
×

MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma

34 Aufrufe

Veröffentlicht am

- 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.

Veröffentlicht in: Internet
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma

  1. 1. Немного о оптимизации производительности Грига Иван Backend developer в компании Smart Gamma
  2. 2. MongoDB — что это? MongoDB — это высокопроизводительная документо- ориентированная база данных без схем данных, которая относиться к не реляционным БД. Структура: содержит в себе множество коллекций, они же содержат множество документов(объектов), которые в свою очередь содержат пары ключ-значение
  3. 3. Документ: Документ – это набор пар “ключ – значение”. Документ имеет динамическую схему. Документ в одной и той же коллекции не обязан иметь один одинаковый набор полей или структуру, а общие поля в коллекции могут иметь различные типы данных. Для хранения MongoDB использует JSON-подобные документы, который называется BSON (Binary JSON). { field1: value1, field2: { embedField1: value, ……………………………….. }, field3: [ value1, value2, …. ] }
  4. 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. 5. Когда стоит и использовать MongoDB У вас нет четкой, заранее описанной структуры данных или состав данных может потом сильно изменится У вас планируется довольно серьезный объем данных Нету большого количества связей между типами данных У вас приложение с интенсивной записью (удобно для логирования чего либо) модно же
  6. 6. О чем пойдет речь: Когда и зачем нужна оптимизация производительности С чего начать Как анализировать запросы Индексы, для чего они нужны Как правильно строить запросы
  7. 7. С чего начать Смотрим MongoDB Log по дефолту /var/log/mongodb/mongod.log Настраиваем и анализируем Database Profiler Анализируем запросы db.collection.explain()
  8. 8. Database Profiler db.setProfilingLevel(level, { slowms: 200 }) - включить профилирование базы данных level 0 Профилировщик выключен и не собирает никаких данных (по умолчанию). 1 Профилировщик собирает данные для операций, которые занимают больше времени, чем значение slowms. 2 Профилировщик собирает данные для всех операций.
  9. 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. 10. Анализируем запросы db.collection.find({}).explain(‘queryPlanner') - детализирует план, выбранный оптимизатором запросов. db.collection.find({}).explain('executionStats') - возвращает статистику выполнения запроса. • executionStats.nReturned количество возвращенных документов. • executionStats.totalKeysExamined: будет 0, если запрос не использует индекс. • executionStats.totalDocsExamined: количество отсканированных документов для получения результата.
  11. 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 } )
  12. 12. Compound Index и сортировка N# Query Index 1 db.data.find().sort({a: 1, b: -1}) {a: 1, b: -1} 2 db.data.find().sort({a: -1, b: 1}) {a: 1, b: -1} 3 db.data.find().sort({b: -1, a: 1}) {a: 1, b: -1} 4 db.data.find().sort({a: 1, b: 1}) {a: 1, b: -1} 5 db.data.find().sort({a: 1}) {a: 1, b: 1, c: 1} 6 db.data.find().sort({a: 1, b: 1}) {a: 1, b: 1, c: 1} 7 db.data.find().sort({a: -1, b: -1}) {a: 1, b: 1, c: 1} 8 db.data.find({a: 5}).sort({ b: 1}) {a: 1, b: 1, c: 1} 9 db.data.find({b: 5}).sort({b: 1}) {a: 1, b: 1, c: 1}
  13. 13. Примеры. Структура документов коллекции { fname: string, isHidden: boolean, ……………………………………………………………….. messages: [ { dataId: string, status: string, …………………………………………… info: { dateTime: date, deviceType: string ………………………………… } }, …………………………………………………… ] }
  14. 14. Пример 1 db.getCollection.find({"fname": "Maxwell", "isHidden": { "$ne": true }, "messages.status": "delivered“}).sort({ "fname": -1 }) .explain('executionStats') До создания индексов { "queryPlanner" : { ………......................................... }, "executionStats" : { "executionSuccess" : true, "nReturned" : 4, "executionTimeMillis" : 2033, "totalKeysExamined" : 0, "totalDocsExamined" : 3019513, ……………………………………………. }, "serverInfo" : { …................................................... }, "ok" : 1.0 } После { "queryPlanner" : { ............................................. }, "executionStats" : { "executionSuccess" : true, "nReturned" : 4, "executionTimeMillis" : 6, "totalKeysExamined" : 194, "totalDocsExamined" : 194, ………………………………………… }, "serverInfo" : { .................................................. }, "ok" : 1.0 }
  15. 15. Пример 2 После создания индексов ничего не изменилось. db.getCollection.aggregate([ { "$unwind": "$messages" }, { "$match": { “messages.info": { "$exists": true }, “messages.info.dateTime": { "$gte": new ISODate("2018-01-01T01:00:00+02:00") } } }, { "$group": { "_id": { "identifier": "$messages.dataId", "deviceType": "$messages.info.deviceType" }, "count": { "$sum": 1 } } } ])
  16. 16. $unwind При агрегации данных $unwind позволяем развернуть поля- подмассивы путём дублирования в выборке родительской сущности для каждого поля такого подмассива. { "_id" : 1, "item" : "ABC1", sizes: [ "S", "M", "L"] } Результат выполнения db.inventory.aggregate( [ { $unwind : "$sizes" } ] ) { "_id" : 1, "item" : "ABC1", "sizes" : "S" } { "_id" : 1, "item" : "ABC1", "sizes" : "M" } { "_id" : 1, "item" : "ABC1", "sizes" : "L" }
  17. 17. Выполнение 3 523 миллисекунды Выполнение 204 миллисекунды db.getCollection.aggregate([ { "$unwind": "$messages" }, { "$match": { “messages.info": { "$exists": true }, “messages.info.dateTime": { "$gte": new ISODate("2018-01-01T01:00:00+02:00") } } }, { "$group": { "_id": { "identifier": "$messages.dataId", "deviceType": "$messages.info.deviceType" }, "count": { "$sum": 1 } } } ]) db.getCollection.aggregate([ { "$match": { “messages.info": { "$exists": true }, “messages.info.dateTime": { "$gte": new ISODate("2018-01-01T01:00:00+02:00") } } }, { "$unwind": "$messages" }, { "$match": { “messages.info": { "$exists": true }, “messages.info.dateTime": { "$gte": new ISODate("2018-01-01T01:00:00+02:00") } } }, { "$group": { "_id": { "identifier": "$messages.dataId", "deviceType": "$messages.info.deviceType" }, "count": { "$sum": 1 } } } ])
  18. 18. $project Передает документы с запрошенными полями к следующему этапу агрегации. Указанные поля могут быть существующими полями из входных документов или вновь вычисленных полей. { "_id" : 1, "item" : "A", sizes: [ "S", "M", "L"] } { "_id" : 2, "item" : "B", sizes: [ "S", "M"] } { "_id" : 3, "item" : “C", sizes: [ "S", "L"] } Результат выполнения db.inventory.aggregate( [ { $project : { _id: 0 , item: 1 } } ] ) { "item" : “A"} { "item" : “B"} { "item" : “C"}
  19. 19. Пример 3. Пагинация. • Выполнение 15.4 секунды db.getCollection.aggregate([ { "$match": {gender: "Male"} }, { "$sort": {"_id": 1} }, { "$skip": 1000000} }, { "$limit": 100} } ]) • Выполнение 7.49 сек. db.getCollection.aggregate([ { "$match": {gender: "Male"} }, { "$sort": {"_id": 1} }, { "$project": {"_id": 1} }, { "$skip": 1000000} }, { "$limit": 1} ]) db.getCollection.aggregate([ { "$match": { $and: [ {gender: "Male"} , {"_id": {$gte: ObjectId(“5bb2f…")}} ] }, { "$sort": {"_id": 1} }, { "$limit": 100} } ])
  20. 20. Советы Хранить документы простыми. Анализ встроенных документов и массивов может быть очень сложным. Кроме того, массивы могут снизить производительность репликации: при каждом изменении массива все значения массива реплицируются! Возвращать в запросе только те поля, которые вам нужны. По возможности не использовать $ne и $nin. hint() - чтобы заставить MongoDB использовать определенный индекс Не забываем про limit() если известно максимальное количество нужных данных maxTimeMS() – иногда полезно ограничить время выполнения запроса
  21. 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. 22. Что дальше Типов индексов много Оптимизация на основе архитектуры приложения Sharding - распределения данных по нескольким машинам.
  23. 23. Спасибо за внимание Вопросы?

×