我正在尝试使用以下查询汇总我收集的一些信息:
db.myCollection.aggregate([
{$match: {survey: ObjectId("54570ff2968d6e492b0e4db7")}},
{$unwind: "$answers"},
{$unwind: "$answers.values"},
{$project: {q: "$answers.question", l: "$answers.values.label"}},
{$group:{
_id: "$l",
total: {$sum: 1},
question: {$first: "$q"}
}
}]
,
{
allowDiskUse: true,
}
);
可以看到示例数据here。
当我汇总相对少量的数据时,性能很好。当我汇总大量数据(20,000个文档)时,我看到大约3.5秒的运行时间,当我针对非常大量的数据(1,000,000个文档)运行它时,我看到1-2分钟的运行时间。
我在myCollection
上有几个索引,但我认为唯一适用于上述查询的索引是{survey: 1, created: 1}
当我包含上述查询的说明时,它会在BTreeCursor
下显示stages.$cursor.plan.cursor
,我相信这意味着该查询正在使用必要的索引(full explain available here)。
我通读了MongoDB's optimization guidelines,似乎我已经在使用适用的那些。
考虑到我已经尝试过的内容,有人可以建议任何有助于改善上述查询性能的内容吗?在试图加快这个人的速度时,有什么显而易见的事情我会失踪吗?
更新 - 包括样本数据:
{
email: "test@test.com,
answers:[
{
question: ObjectId("54571089968d6e492b10133d"),
values: [{label: "option 1", value: true}]
}
]
},
{
email: "another@test.com,
answers:[
{
question: ObjectId("54571089968d6e492b10133d"),
values: [{label: "option 1", value: true}]
}
]
},
,
{
email: "one@more.com,
answers:[
{
question: ObjectId("54571089968d6e492b10133d"),
values: [
{label: "option 2", value: true},
{label: "option 1", value: true}
]
}
]
}
更新2 - 包括解释:
{
"stages" : [
{
"$cursor" : {
"query" : {
"survey" : ObjectId("54570ff2968d6e492b0e4db7")
},
"fields" : {
"answers" : 1,
"_id" : 1
},
"plan" : {
"cursor" : "BtreeCursor ",
"isMultiKey" : false,
"scanAndOrder" : false,
"indexBounds" : {
"survey" : [
[
ObjectId("54570ff2968d6e492b0e4db7"),
ObjectId("54570ff2968d6e492b0e4db7")
]
],
"created" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
},
"allPlans" : [
{
"cursor" : "BtreeCursor ",
"isMultiKey" : false,
"scanAndOrder" : false,
"indexBounds" : {
"survey" : [
[
ObjectId("54570ff2968d6e492b0e4db7"),
ObjectId("54570ff2968d6e492b0e4db7")
]
],
"created" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
]
}
}
},
{
"$project" : {
"answers" : true
}
},
{
"$unwind" : "$answers"
},
{
"$unwind" : "$answers.values"
},
{
"$project" : {
"q" : "$answers.question",
"l" : "$answers.values.label"
}
},
{
"$group" : {
"_id" : "$l",
"total" : {
"$sum" : {
"$const" : 1
}
},
"question" : {
"$first" : "$q"
}
}
}
],
"ok" : 1
}