MongoDB 聚合查询期间未使用索引
Indexing not utilized during the MongoDB aggregation query
我卡在了 MongoDB 聚合查询的某处。我试图从包含 110M 条记录的数据库中生成摘要报告。在报告生成过程中,我遇到了以下问题
1). 即使集合被编入索引,它们也不会被用于搜索。
2). 一旦查询执行完成,数据库服务器的内存不会减少。
3)查询需要相当长的时间return结果。
我正在使用 mongodb Atlas v4.2.8
示例文档
{
"_id": {
"$oid": "5eb122f714d0510011e3a184"
},
"from": "Star_friends",
"to": "94713414047",
"accountName": "ZM",
"accountId": "ZM",
"campaignName": "test 1",
"campaignId": "5eb122f1e921c3001922f73c",
"campaignType": "BULK",
"status": {
"$numberInt": "3"
},
"reason": "No Routing",
"channel": "sms",
"messageType": {
"$numberInt": "1"
},
"event": "MT",
"content": "test 132",
"credit": {
"$numberInt": "1"
},
"msgId": "",
"createdDateTime": "2020-05-05T13:55:27.743Z",
"updatedTime": "2020-05-05T13:55:27.745Z",
"uDate": "2020-05-05",
"operator": "mobitel"
}
我的查询如下
db.getCollection('report').aggregate([{
"$match": {
"createdDateTime": {
"$gt": "2020-09-14T00:00:01.000Z",
"$lt": "2020-09-15T23:59:99.999Z"
},
"messageType": {
"$in": [1, 2]
},
"channel": {
"$in": ["sms", "viber", "whatsapp"]
},
"accountId": {
"$in": ["ZM", "KEELLS"]
}
}
}, {
"$project": {
"_id": 0,
"channel": 1,
"messageType": 1,
"accountName": 1,
"accountId": 1,
"createdDateTime": 1,
"uDate": 1,
"credit": 1,
"status": 1
}
}, {
"$group": {
"_id": {
"channel": "$channel",
"messageType": "$messageType",
"accountName": "$accountName",
"accountId": "$accountId",
"filteredDate": {
"$substr": ["$createdDateTime", 0, 7]
},
"sortDate": "$uDate"
},
"total": {
"$sum": "$credit"
},
"send": {
"$sum": {
"$cond": [{
"$in": ["$status", [2, 15, 1, 14, 6, 17, 4, 5]]
}, "$credit", 0]
}
},
"delivered": {
"$sum": {
"$cond": [{
"$in": ["$status", [6, 17, 4]]
},
"$credit",
0
]
}
},
"deliveryFailed": {
"$sum": {
"$cond": [{
"$in": ["$status", [12, 5]]
}, "$credit", 0]
}
},
"failed": {
"$sum": {
"$cond": [{
"$in": ["$status", [3]]
}, "$credit", 0]
}
},
"datass": {
"$addToSet": {
"channel": "$channel",
"messageType": "$messageType",
"accountName": "$accountName",
"accountId": "$accountId",
"filteredDate": {
"$substr": ["$createdDateTime", 0, 7]
},
"sortDate": "$uDate"
}
}
}
}, {
"$unwind": "$datass"
}, {
"$project": {
"_id": 0
}
}, {
"$sort": {
"datass.sortDate": -1
}
}])
索引如下
accountId_1 / accountId_1_createdDateTime_-1 / campaignId_-1 / channel_1 / createdDateTime_-1 / messageType_1 / msgId_-1 / msgId_-1_status_1
如果有人能帮助我,我将不胜感激
谢谢
您给我们提供的信息很少。
像这样 return 平均查询应该有多少文档?
执行上述查询需要多长时间?
我在这里看到的是您的匹配管道很好,因为您正试图通过索引的字段过滤掉文档。
但是这里的“性能气味”是你的 $sort 函数,它对非索引字段进行排序。尝试在 $match.
之后立即进行排序
多试一试,找出管道的哪个阶段是性能瓶颈。
我已经通过更改索引解决了我的问题
accountId_1_createdDateTime_-1/
msgId_-1_status_1/
accountId_1_messageType_1_channel_1_createdDateTime_1_accountName_1_uDate_1_credit_1_status_1
我卡在了 MongoDB 聚合查询的某处。我试图从包含 110M 条记录的数据库中生成摘要报告。在报告生成过程中,我遇到了以下问题 1). 即使集合被编入索引,它们也不会被用于搜索。 2). 一旦查询执行完成,数据库服务器的内存不会减少。 3)查询需要相当长的时间return结果。
我正在使用 mongodb Atlas v4.2.8 示例文档
{
"_id": {
"$oid": "5eb122f714d0510011e3a184"
},
"from": "Star_friends",
"to": "94713414047",
"accountName": "ZM",
"accountId": "ZM",
"campaignName": "test 1",
"campaignId": "5eb122f1e921c3001922f73c",
"campaignType": "BULK",
"status": {
"$numberInt": "3"
},
"reason": "No Routing",
"channel": "sms",
"messageType": {
"$numberInt": "1"
},
"event": "MT",
"content": "test 132",
"credit": {
"$numberInt": "1"
},
"msgId": "",
"createdDateTime": "2020-05-05T13:55:27.743Z",
"updatedTime": "2020-05-05T13:55:27.745Z",
"uDate": "2020-05-05",
"operator": "mobitel"
}
我的查询如下
db.getCollection('report').aggregate([{
"$match": {
"createdDateTime": {
"$gt": "2020-09-14T00:00:01.000Z",
"$lt": "2020-09-15T23:59:99.999Z"
},
"messageType": {
"$in": [1, 2]
},
"channel": {
"$in": ["sms", "viber", "whatsapp"]
},
"accountId": {
"$in": ["ZM", "KEELLS"]
}
}
}, {
"$project": {
"_id": 0,
"channel": 1,
"messageType": 1,
"accountName": 1,
"accountId": 1,
"createdDateTime": 1,
"uDate": 1,
"credit": 1,
"status": 1
}
}, {
"$group": {
"_id": {
"channel": "$channel",
"messageType": "$messageType",
"accountName": "$accountName",
"accountId": "$accountId",
"filteredDate": {
"$substr": ["$createdDateTime", 0, 7]
},
"sortDate": "$uDate"
},
"total": {
"$sum": "$credit"
},
"send": {
"$sum": {
"$cond": [{
"$in": ["$status", [2, 15, 1, 14, 6, 17, 4, 5]]
}, "$credit", 0]
}
},
"delivered": {
"$sum": {
"$cond": [{
"$in": ["$status", [6, 17, 4]]
},
"$credit",
0
]
}
},
"deliveryFailed": {
"$sum": {
"$cond": [{
"$in": ["$status", [12, 5]]
}, "$credit", 0]
}
},
"failed": {
"$sum": {
"$cond": [{
"$in": ["$status", [3]]
}, "$credit", 0]
}
},
"datass": {
"$addToSet": {
"channel": "$channel",
"messageType": "$messageType",
"accountName": "$accountName",
"accountId": "$accountId",
"filteredDate": {
"$substr": ["$createdDateTime", 0, 7]
},
"sortDate": "$uDate"
}
}
}
}, {
"$unwind": "$datass"
}, {
"$project": {
"_id": 0
}
}, {
"$sort": {
"datass.sortDate": -1
}
}])
索引如下
accountId_1 / accountId_1_createdDateTime_-1 / campaignId_-1 / channel_1 / createdDateTime_-1 / messageType_1 / msgId_-1 / msgId_-1_status_1
如果有人能帮助我,我将不胜感激
谢谢
您给我们提供的信息很少。 像这样 return 平均查询应该有多少文档? 执行上述查询需要多长时间?
我在这里看到的是您的匹配管道很好,因为您正试图通过索引的字段过滤掉文档。 但是这里的“性能气味”是你的 $sort 函数,它对非索引字段进行排序。尝试在 $match.
之后立即进行排序多试一试,找出管道的哪个阶段是性能瓶颈。
我已经通过更改索引解决了我的问题
accountId_1_createdDateTime_-1/ msgId_-1_status_1/ accountId_1_messageType_1_channel_1_createdDateTime_1_accountName_1_uDate_1_credit_1_status_1