SlideShare une entreprise Scribd logo
1  sur  23
Немного о оптимизации
производительности
Грига Иван
Backend developer в компании Smart Gamma
MongoDB — что это?
MongoDB — это высокопроизводительная документо-
ориентированная база данных без схем данных, которая
относиться к не реляционным БД.
Структура: содержит в себе множество коллекций, они же
содержат множество документов(объектов), которые в свою
очередь содержат пары ключ-значение
Документ:
Документ – это набор пар “ключ –
значение”. Документ имеет
динамическую схему.
Документ в одной и той же
коллекции не обязан иметь один
одинаковый набор полей или структуру, а
общие поля в коллекции могут иметь
различные типы данных.
Для хранения MongoDB использует
JSON-подобные документы, который
называется BSON (Binary JSON).
{
field1: value1,
field2: {
embedField1: value,
………………………………..
},
field3: [
value1,
value2, ….
]
}
Сравнение с MySQL
MySQL MongoDB
ACID Transactions ACID Transactions
Table Collection
Row Document
Column Field
Index Index
JOINs Embedded documents, $lookup & $graphLookup
GROUP_BY Aggregation Pipeline
Когда стоит и использовать MongoDB
У вас нет четкой, заранее описанной структуры данных или
состав данных может потом сильно изменится
У вас планируется довольно серьезный объем данных
Нету большого количества связей между типами данных
У вас приложение с интенсивной записью (удобно для
логирования чего либо)
модно же
О чем пойдет речь:
Когда и зачем нужна оптимизация производительности
С чего начать
Как анализировать запросы
Индексы, для чего они нужны
Как правильно строить запросы
С чего начать
Смотрим MongoDB Log
по дефолту /var/log/mongodb/mongod.log
Настраиваем и анализируем
Database Profiler
Анализируем запросы
db.collection.explain()
Database Profiler
db.setProfilingLevel(level, { slowms: 200 }) - включить
профилирование базы данных
level
0 Профилировщик выключен и не собирает никаких
данных (по умолчанию).
1 Профилировщик собирает данные для операций,
которые занимают больше времени, чем значение
slowms.
2 Профилировщик собирает данные для всех операций.
Примеры использования профилировщика
• Получить последние 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 } }
])
Анализируем запросы
db.collection.find({}).explain(‘queryPlanner') - детализирует план,
выбранный оптимизатором запросов.
db.collection.find({}).explain('executionStats') - возвращает
статистику выполнения запроса.
• executionStats.nReturned количество возвращенных документов.
• executionStats.totalKeysExamined: будет 0, если запрос не использует
индекс.
• executionStats.totalDocsExamined: количество отсканированных
документов для получения результата.
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 } )
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}
Примеры. Структура документов коллекции
{
fname: string,
isHidden: boolean,
………………………………………………………………..
messages: [
{
dataId: string,
status: string,
……………………………………………
info: {
dateTime: date,
deviceType: string
…………………………………
}
},
……………………………………………………
]
}
Пример 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
}
Пример 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 }
}
}
])
$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" }
Выполнение 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 }
}
} ])
$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"}
Пример 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} }
])
Советы
Хранить документы простыми.
Анализ встроенных документов и массивов может быть очень сложным. Кроме того, массивы могут снизить
производительность репликации: при каждом изменении массива все значения массива реплицируются!
Возвращать в запросе только те поля, которые вам нужны.
По возможности не использовать $ne и $nin.
hint() - чтобы заставить MongoDB использовать определенный
индекс
Не забываем про limit() если известно максимальное количество
нужных данных
maxTimeMS() – иногда полезно ограничить время выполнения
запроса
Aggregation optimization
Если возможно добавляйте $match + $sort в начало запроса
Всегда используйте последовательность, такую как $match +
$projection, $match1 + $projection1
Ставить $project, $unwind, and $group в конец запроса
Операторы сравнения $lt и $gt вместо $skip для пагинации
Правильная последовательность $sort + $limit +$skip
Если в запросе идут $match + $match один за другим то
объедините их используя $and
Флаг allowDiskUse: true
Что дальше
Типов индексов много
Оптимизация на основе архитектуры приложения
Sharding - распределения данных по нескольким
машинам.
Спасибо за внимание
Вопросы?

Contenu connexe

Tendances

JavaScript-библиотека
JavaScript-библиотекаJavaScript-библиотека
JavaScript-библиотекаVasya Petrov
 
Магия метаклассов
Магия метаклассовМагия метаклассов
Магия метаклассовAndrey Zakharevich
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4Technopark
 
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...Ontico
 
Новое в Mongodb 2.4
Новое в Mongodb 2.4Новое в Mongodb 2.4
Новое в Mongodb 2.4Gleb Lebedev
 
Быть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря GroovyБыть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря GroovyEvgeny Kompaniyets
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка DjangoVladimir Rudnyh
 
Подводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, IПодводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, IVladimir Kochetkov
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NETPositive Hack Days
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиГлеб Тарасов
 
Web весна 2013 лекция 4
Web весна 2013 лекция 4Web весна 2013 лекция 4
Web весна 2013 лекция 4Technopark
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловGeeksLab Odessa
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в DjangoMoscowDjango
 
Multimodel Database Caché
Multimodel Database CachéMultimodel Database Caché
Multimodel Database CachéTimur Safin
 
Практическое применение MongoDB Aggregation Framework
Практическое применение MongoDB Aggregation FrameworkПрактическое применение MongoDB Aggregation Framework
Практическое применение MongoDB Aggregation FrameworkДенис Кравченко
 
AlgoCollections (RUS)
AlgoCollections (RUS)AlgoCollections (RUS)
AlgoCollections (RUS)Anton Bukov
 
Перспективы функционального подхода
Перспективы функционального подходаПерспективы функционального подхода
Перспективы функционального подходаIgor Kashkuta
 
Что API Карт забыл на сервере — Антон Корзунов
Что API Карт забыл на сервере — Антон КорзуновЧто API Карт забыл на сервере — Антон Корзунов
Что API Карт забыл на сервере — Антон КорзуновYandex
 

Tendances (19)

JavaScript-библиотека
JavaScript-библиотекаJavaScript-библиотека
JavaScript-библиотека
 
Магия метаклассов
Магия метаклассовМагия метаклассов
Магия метаклассов
 
Web осень 2012 лекция 4
Web осень 2012 лекция 4Web осень 2012 лекция 4
Web осень 2012 лекция 4
 
MongoDB@addconf
MongoDB@addconfMongoDB@addconf
MongoDB@addconf
 
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...ObjectManager, или как работать с большим количеством объектов на карте, Мари...
ObjectManager, или как работать с большим количеством объектов на карте, Мари...
 
Новое в Mongodb 2.4
Новое в Mongodb 2.4Новое в Mongodb 2.4
Новое в Mongodb 2.4
 
Быть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря GroovyБыть в 10 раз эффективнее благодаря Groovy
Быть в 10 раз эффективнее благодаря Groovy
 
Профилирование и отладка Django
Профилирование и отладка DjangoПрофилирование и отладка Django
Профилирование и отладка Django
 
Подводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, IПодводные камни прикладной криптографии, I
Подводные камни прикладной криптографии, I
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
 
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с даннымиШкола-студия разработки для iOS. Лекция 4. Работа с данными
Школа-студия разработки для iOS. Лекция 4. Работа с данными
 
Web весна 2013 лекция 4
Web весна 2013 лекция 4Web весна 2013 лекция 4
Web весна 2013 лекция 4
 
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким ХалиловWebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
WebCamp: Developer Day: Parse'им бэкенд - Аким Халилов
 
Производительность в Django
Производительность в DjangoПроизводительность в Django
Производительность в Django
 
Multimodel Database Caché
Multimodel Database CachéMultimodel Database Caché
Multimodel Database Caché
 
Практическое применение MongoDB Aggregation Framework
Практическое применение MongoDB Aggregation FrameworkПрактическое применение MongoDB Aggregation Framework
Практическое применение MongoDB Aggregation Framework
 
AlgoCollections (RUS)
AlgoCollections (RUS)AlgoCollections (RUS)
AlgoCollections (RUS)
 
Перспективы функционального подхода
Перспективы функционального подходаПерспективы функционального подхода
Перспективы функционального подхода
 
Что API Карт забыл на сервере — Антон Корзунов
Что API Карт забыл на сервере — Антон КорзуновЧто API Карт забыл на сервере — Антон Корзунов
Что API Карт забыл на сервере — Антон Корзунов
 

Similaire à MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma

Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6Technopark
 
Cтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBCтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBDmitry Viskov
 
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Ivan Muratov
 
Разработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительностьРазработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительностьВадим Воробьев
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному кодуVasiliy Deynega
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agencyit-people
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupMail.ru Group
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...CocoaHeads
 
Next Gen Applications
Next Gen ApplicationsNext Gen Applications
Next Gen ApplicationsVittorio Cioe
 
MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?Alexey Tokar
 
2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса
2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса
2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервисаОмские ИТ-субботники
 
Python Meetup
Python Meetup Python Meetup
Python Meetup iQSpace
 
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Ontico
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
Влад Ковташ — Yap Database
Влад Ковташ — Yap DatabaseВлад Ковташ — Yap Database
Влад Ковташ — Yap DatabaseCocoaHeads
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
MongoDB. Фокус на тестирование
MongoDB. Фокус на тестированиеMongoDB. Фокус на тестирование
MongoDB. Фокус на тестированиеUladzimir Kryvenka
 

Similaire à MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma (20)

Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6
 
Js fuckworks
Js fuckworksJs fuckworks
Js fuckworks
 
Cтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBCтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDB
 
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
 
Scala on android
Scala on androidScala on android
Scala on android
 
Разработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительностьРазработка крупного Standalone проекта на юнити: улучшаем производительность
Разработка крупного Standalone проекта на юнити: улучшаем производительность
 
C#. От основ к эффективному коду
C#. От основ к эффективному кодуC#. От основ к эффективному коду
C#. От основ к эффективному коду
 
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
View как чистая функция от состояния базы данных  - Илья Беда, bro.agencyView как чистая функция от состояния базы данных  - Илья Беда, bro.agency
View как чистая функция от состояния базы данных - Илья Беда, bro.agency
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
 
Next Gen Applications
Next Gen ApplicationsNext Gen Applications
Next Gen Applications
 
MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?MongoDB в продакшен - миф или реальность?
MongoDB в продакшен - миф или реальность?
 
Vba 07
Vba 07Vba 07
Vba 07
 
2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса
2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса
2015 09-05 02 Сергей Сорокин. Обзор и анализ мобильного backend сервиса
 
Python Meetup
Python Meetup Python Meetup
Python Meetup
 
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
Влад Ковташ — Yap Database
Влад Ковташ — Yap DatabaseВлад Ковташ — Yap Database
Влад Ковташ — Yap Database
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
MongoDB. Фокус на тестирование
MongoDB. Фокус на тестированиеMongoDB. Фокус на тестирование
MongoDB. Фокус на тестирование
 

Plus de Evgeniy Kuzmin

Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Evgeniy Kuzmin
 
Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...
Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...
Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...Evgeniy Kuzmin
 
Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...
Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...
Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...Evgeniy Kuzmin
 
Continuous Integration/ Continuous Delivery of web applications
Continuous Integration/ Continuous Delivery of web applicationsContinuous Integration/ Continuous Delivery of web applications
Continuous Integration/ Continuous Delivery of web applicationsEvgeniy Kuzmin
 
Тестирование как панацея для жизни и развития проекта
Тестирование как панацея для жизни и развития проекта Тестирование как панацея для жизни и развития проекта
Тестирование как панацея для жизни и развития проекта Evgeniy Kuzmin
 
Спасение через тестирование - история одного проекта
Спасение через тестирование - история одного проектаСпасение через тестирование - история одного проекта
Спасение через тестирование - история одного проектаEvgeniy Kuzmin
 
Behaivior Driven Development - from the tests to the business logic in a sing...
Behaivior Driven Development - from the tests to the business logic in a sing...Behaivior Driven Development - from the tests to the business logic in a sing...
Behaivior Driven Development - from the tests to the business logic in a sing...Evgeniy Kuzmin
 
Smart Gamma - Real-Time Web applications with PHP and Websocket.
Smart Gamma - Real-Time Web applications with PHP and Websocket.Smart Gamma - Real-Time Web applications with PHP and Websocket.
Smart Gamma - Real-Time Web applications with PHP and Websocket.Evgeniy Kuzmin
 

Plus de Evgeniy Kuzmin (8)

Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
Continuous integration / continuous delivery of web applications, Eugen Kuzmi...
 
Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...
Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...
Contract testing. Isolated testing of microservices with pact.io - Evgeniy Ku...
 
Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...
Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...
Contract testing - isolated testing of microservices - Symfony Camp 2018, Evg...
 
Continuous Integration/ Continuous Delivery of web applications
Continuous Integration/ Continuous Delivery of web applicationsContinuous Integration/ Continuous Delivery of web applications
Continuous Integration/ Continuous Delivery of web applications
 
Тестирование как панацея для жизни и развития проекта
Тестирование как панацея для жизни и развития проекта Тестирование как панацея для жизни и развития проекта
Тестирование как панацея для жизни и развития проекта
 
Спасение через тестирование - история одного проекта
Спасение через тестирование - история одного проектаСпасение через тестирование - история одного проекта
Спасение через тестирование - история одного проекта
 
Behaivior Driven Development - from the tests to the business logic in a sing...
Behaivior Driven Development - from the tests to the business logic in a sing...Behaivior Driven Development - from the tests to the business logic in a sing...
Behaivior Driven Development - from the tests to the business logic in a sing...
 
Smart Gamma - Real-Time Web applications with PHP and Websocket.
Smart Gamma - Real-Time Web applications with PHP and Websocket.Smart Gamma - Real-Time Web applications with PHP and Websocket.
Smart Gamma - Real-Time Web applications with PHP and Websocket.
 

MongoDB - About Performance Optimization, Ivan Griga - Smart Gamma

  • 1. Немного о оптимизации производительности Грига Иван Backend developer в компании Smart Gamma
  • 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 } )
  • 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. Примеры. Структура документов коллекции { fname: string, isHidden: boolean, ……………………………………………………………….. messages: [ { dataId: string, status: string, …………………………………………… info: { dateTime: date, deviceType: string ………………………………… } }, …………………………………………………… ] }
  • 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. Пример 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. $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. Выполнение 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. $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. Пример 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. Советы Хранить документы простыми. Анализ встроенных документов и массивов может быть очень сложным. Кроме того, массивы могут снизить производительность репликации: при каждом изменении массива все значения массива реплицируются! Возвращать в запросе только те поля, которые вам нужны. По возможности не использовать $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 - распределения данных по нескольким машинам.