#mongodb #aggregation-framework
#mongodb #платформа агрегации
Вопрос:
Мы используем mongodb для всех наших аналитических запросов. Ниже я вставил план запроса одного из запросов. Коллекция содержит около 1,3 миллиона записей, и этот запрос выполняется для одного сопоставления (которое может содержать не более 40 тысяч записей), которое указано как assignment_supply_entity_mapping_id в конвейере сопоставления. Этот запрос в настоящее время занимает 553 мс, несмотря на IXSCAN для assignment_supply_entity_mapping_id.
Мой вопрос в том, не слишком ли много времени требуется, учитывая объем запрашиваемых данных. Если да, то как мне его оптимизировать? Я подозреваю, что причиной является вложенный фильтр. Это правда?
{
"op":"command",
"ns":"analytics_new.leads",
"command":{
"aggregate":"leads",
"pipeline":[
{
"$project":{
"logs":0
}
},
{
"$match":{
"$and":[
{
"assignment_supply_entity_mapping_id":{
"$in":[
1011,
850,
998,
840
]
}
},
{
"tags.is_duplicate":{
"$ne":true
}
},
{
"tags.is_abandoned":{
"$ne":true
}
},
{
"tags.is_archived":{
"$ne":true
}
},
{
"id":{
"$nin":[
]
}
},
{
"$or":[
{
"all_agents":{
"$in":[
2765,
2766,
193,
994,
1007,
1188,
1376,
1769,
2421,
2422,
2423,
2424,
115,
133,
149,
193,
441,
747,
884,
994,
1003,
1007,
1100,
1188,
1378,
1612,
1769,
1964,
1966,
1967,
1968,
1969,
1970,
1971,
1973,
2333,
2364,
3170,
3318,
3320,
3757,
4071,
4294,
4297,
1965,
1188,
994,
193,
715,
1599,
2333,
3170,
2424,
1972,
1007,
2423,
1377,
1378,
1970,
1100,
649,
1950,
1376,
441,
1612,
939,
1966,
1971,
133,
1952,
1969,
337,
1973,
712,
3318,
2392,
115,
708,
1037,
1964,
2421,
1967,
537,
1769,
1968,
1956,
3320,
2364,
978,
1974,
149,
996,
1003,
1951,
2610,
2422,
884
]
}
},
{
"$and":[
{
"agent.id":{
"$exists":false
}
},
{
"$or":[
{
"$and":[
{
"current_status.id":5
},
{
"$or":[
{
"recently_contacted_agent_ids":{
"$exists":false
}
},
{
"recently_contacted_agent_ids":{
"$in":[
2765,
2766,
193,
994,
1007,
1188,
1376,
1769,
2421,
2422,
2423,
2424,
115,
133,
149,
193,
441,
747,
884,
994,
1003,
1007,
1100,
1188,
1378,
1612,
1769,
1964,
1966,
1967,
1968,
1969,
1970,
1971,
1973,
2333,
2364,
3170,
3318,
3320,
3757,
4071,
4294,
4297,
1965,
1188,
994,
193,
715,
1599,
2333,
3170,
2424,
1972,
1007,
2423,
1377,
1378,
1970,
1100,
649,
1950,
1376,
441,
1612,
939,
1966,
1971,
133,
1952,
1969,
337,
1973,
712,
3318,
2392,
115,
708,
1037,
1964,
2421,
1967,
537,
1769,
1968,
1956,
3320,
2364,
978,
1974,
149,
996,
1003,
1951,
2610,
2422,
884
]
}
}
]
}
]
},
{
"current_status.id":{
"$in":[
4,
1,
2,
12
]
}
}
]
}
]
}
]
}
]
}
},
{
"$group":{
"_id":{
"channel":"$lead_origin"
},
"booking_done":{
"$sum":{
"$cond":[
{
"$and":[
{
"$ne":[
{
"$type":"$status_timestamps.booking_done_timestamp"
},
"missing"
]
},
{
"$gt":[
"$status_timestamps.booking_done_timestamp",
"$status_timestamps.failed_timestamp"
]
}
]
},
1,
0
]
}
},
"failed":{
"$sum":{
"$cond":[
{
"$ne":[
{
"$type":"$status_timestamps.failed_timestamp"
},
"missing"
]
},
1,
0
]
}
},
"failed_after_visit":{
"$sum":{
"$cond":[
{
"$and":[
{
"$and":[
{
"$ne":[
{
"$type":"$status_timestamps.failed_timestamp"
},
"missing"
]
},
{
"$ne":[
{
"$type":"$status_timestamps.visit_done_timestamp"
},
"missing"
]
}
]
},
{
"$gt":[
"$status_timestamps.failed_timestamp",
"$status_timestamps.visit_done_timestamp"
]
}
]
},
1,
0
]
}
},
"junk":{
"$sum":{
"$cond":[
{
"$ne":[
{
"$type":"$status_timestamps.junk_timestamp"
},
"missing"
]
},
1,
0
]
}
},
"received":{
"$sum":1
},
"visit_done":{
"$sum":{
"$cond":[
{
"$ne":[
{
"$type":"$status_timestamps.visit_done_timestamp"
},
"missing"
]
},
1,
0
]
}
}
}
}
],
"cursor":{
},
"$db":"analytics_new"
},
"keysExamined":31080,
"docsExamined":31076,
"cursorExhausted":true,
"numYield":249,
"locks":{
"Global":{
"acquireCount":{
"r":NumberLong(508)
}
},
"Database":{
"acquireCount":{
"r":NumberLong(254)
}
},
"Collection":{
"acquireCount":{
"r":NumberLong(254)
}
}
},
"nreturned":6,
"responseLength":905,
"protocol":"op_query",
"millis":553,
"planSummary":"IXSCAN { assignment_supply_entity_mapping_id: 1, created_at: -1 }",
"ts": ISODate("2019-03-04T08:28:57.143 Z"),
"client":"172.31.18.209",
"allUsers":[
],
"user":""
}
Комментарии:
1. сколько документов возвращает первый
$match
?"$match":{ "$and":[ { "assignment_supply_entity_mapping_id":{ "$in":[ ... ] } },
и сколько времени требуется для его выполнения (как простого запроса)?2. Он возвращает 25998 документов, когда я запускаю db.find(match_query).count(). Для его выполнения требуется 216 мс. Я проверил
executionTimeInMillis
вexecutionStats
. Кроме того, разве это не на более высокой стороне? разве IXSCAN для такого количества документов не должен быть быстрее?3. Это зависит от того, насколько велики документы, насколько загружена база данных другими операциями и т.д.. Попробуйте создать индекс только на
assignment_supply_entity_mapping_id: 1
возможно, это уменьшит размер индекса и, следовательно, время сканирования. После этого, возможно, также попробуйте создать разреженный индекс docs.mongodb.com/manual/core/index-sparse4. Спасибо за ответ.
assignment_supply_entity_mapping_id
наверняка будет присутствовать в каждом документе, поэтому разреженный индекс здесь не поможет, а составной индекс{assignment_supply_entity_mapping_id: 1, created_at: -1}
assignment_supply_entity_mapping_id: 1
будет примерно иметь тот же размер, что и индекс на, ,. Нагрузка на сервер также не такая большая. Размер документа также вызывает у меня беспокойство, в настоящее время avgObjectSize составляет около 5 КБ. Достаточно ли он большой? Я также уменьшил размер документа до 2 КБ (среднее значение), но по-прежнему не обнаружил каких-либо существенных улучшений.5.насколько велика база данных? все ли это помещается в оперативную память? вот несколько полезных ссылок: emptysqua.re/blog/optimizing-mongodb-compound-indexes docs.mongodb.com/manual/faq/diagnostics /… docs.mongodb.com/manual/tutorial/ensure-indexes-fit-ram