【发布时间】:2016-06-29 10:40:20
【问题描述】:
我正在使用 mongoose 来计算与某个查询匹配的文档数。我对这个查询的索引是:{createdAt: -1, status: -1, oId: -1}
Mongo 版本为 3.2,集合中的文档数量约为 175 万。
如果我这样做:
model.find({
createdAt: {'$gte': threeMonths, '$lt': today},
status: {'$in': model.STATUS_SET}
}).select({_id: 0, status: 1}).count().then((c) => result[alias] = c)
需要 2 分钟以上。但如果我这样做:
model.find({
createdAt: {'$gte': threeMonths, '$lt': today},
status: {'$in': model.STATUS_SET}
}).select({_id: 0, status: 1}).lean().then((c) => result[alias] = c.length)
然后大约需要 2.5 秒。
我做错了什么?我可以做些什么来帮助加快速度?
编辑:解释日志。
计数:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 82671,
"totalKeysExamined" : 1749689,
"totalDocsExamined" : 1643722,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 80960,
"works" : 1750066,
"advanced" : 0,
"needTime" : 1749689,
"needFetch" : 376,
"saveState" : 14662,
"restoreState" : 14662,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 1643722,
"nSkipped" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 1643722,
"executionTimeMillisEstimate" : 80890,
"works" : 1750065,
"advanced" : 1643722,
"needTime" : 105967,
"needFetch" : 376,
"saveState" : 14662,
"restoreState" : 14662,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1643722,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1643722,
"executionTimeMillisEstimate" : 3800,
"works" : 1749689,
"advanced" : 1643722,
"needTime" : 105967,
"needFetch" : 0,
"saveState" : 14662,
"restoreState" : 14662,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"createdAt" : -1,
"status" : -1,
"oId" : -1
},
"indexName" : "moderatedContent",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"createdAt" : [
"(new Date(1467195213000), new Date(1459246413000)]"
],
"status" : [
"[\"UNDECIDED\", \"UNDECIDED\"]",
"[\"APPROVED\", \"APPROVED\"]"
],
"oId" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 1749689,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"allPlansExecution" : [ ]
}
用于查找。
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1643722,
"executionTimeMillis" : 1216,
"totalKeysExamined" : 1749689,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "PROJECTION",
"nReturned" : 1643722,
"executionTimeMillisEstimate" : 1080,
"works" : 1749690,
"advanced" : 1643722,
"needTime" : 105967,
"needFetch" : 0,
"saveState" : 13669,
"restoreState" : 13669,
"isEOF" : 1,
"invalidates" : 0,
"transformBy" : {
"_id" : 0,
"status" : 1
},
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1643722,
"executionTimeMillisEstimate" : 920,
"works" : 1749690,
"advanced" : 1643722,
"needTime" : 105967,
"needFetch" : 0,
"saveState" : 13669,
"restoreState" : 13669,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"createdAt" : -1,
"status" : -1,
"oId" : -1
},
"indexName" : "moderatedContent",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"createdAt" : [
"(new Date(1467195213000), new Date(1459246413000)]"
],
"status" : [
"[\"UNDECIDED\", \"UNDECIDED\"]",
"[\"APPROVED\", \"APPROVED\"]"
],
"oId" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 1749689,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
}
对于光标中第一个带有 .explain() 的帖子:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 89191,
"totalKeysExamined" : 1749689,
"totalDocsExamined" : 1643722,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 83400,
"works" : 1751709,
"advanced" : 0,
"needTime" : 1749689,
"needFetch" : 2019,
"saveState" : 15648,
"restoreState" : 15648,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 1643722,
"nSkipped" : 0,
"inputStage" : {
"stage" : "FETCH",
"nReturned" : 1643722,
"executionTimeMillisEstimate" : 83260,
"works" : 1751708,
"advanced" : 1643722,
"needTime" : 105967,
"needFetch" : 2019,
"saveState" : 15648,
"restoreState" : 15648,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1643722,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1643722,
"executionTimeMillisEstimate" : 8290,
"works" : 1749689,
"advanced" : 1643722,
"needTime" : 105967,
"needFetch" : 0,
"saveState" : 15648,
"restoreState" : 15648,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"createdAt" : -1,
"status" : -1,
"oId" : -1
},
"indexName" : "moderatedContent",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"createdAt" : [
"(new Date(1467195213000), new Date(1459246413000)]"
],
"status" : [
"[\"UNDECIDED\", \"UNDECIDED\"]",
"[\"APPROVED\", \"APPROVED\"]"
],
"oId" : [
"[MaxKey, MinKey]"
]
},
"keysExamined" : 1749689,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
}
}
【问题讨论】:
-
使用 explain 方法检查发生了什么。你能同时发布两个解释日志吗?
-
@TiagoBértolo 已发布。
-
您的解释有问题。他不应该从计数开始。
-
你能发布这个命令的解释吗? model.explain().find({createdAt: {'$gte': threeMonths, '$lt': today},status: {'$in': model.STATUS_SET}}).count()
-
这个不提供执行统计数据。
标签: javascript node.js mongodb mongoose