推荐答案
在 MongoDB 中,可以使用 explain() 方法来查看查询的执行计划。具体操作如下:
db.collection.find({ query }).explain("executionStats")其中,query 是你要执行的查询条件。explain() 方法可以接受不同的参数来返回不同详细程度的执行计划信息。常用的参数包括:
"queryPlanner":返回查询优化器选择的执行计划。"executionStats":返回查询优化器选择的执行计划以及执行统计信息。"allPlansExecution":返回所有候选执行计划的详细信息。
本题详细解读
1. explain() 方法的作用
explain() 方法是 MongoDB 提供的一个用于分析查询性能的工具。通过它,你可以了解 MongoDB 是如何执行某个查询的,包括索引的使用情况、查询的扫描方式、返回的文档数量等。
2. 参数详解
"queryPlanner":这是默认参数,返回查询优化器选择的执行计划。它包含了查询的索引选择、查询计划的结构等信息,但不包含实际的执行统计信息。"executionStats":这个参数不仅返回查询优化器选择的执行计划,还包含了实际的执行统计信息,如查询的执行时间、扫描的文档数量、返回的文档数量等。这是最常用的参数,因为它提供了足够的信息来评估查询的性能。"allPlansExecution":这个参数返回所有候选执行计划的详细信息,包括被优化器拒绝的计划。它可以帮助你了解优化器为什么选择了某个特定的执行计划。
3. 执行计划的关键字段
在执行计划的结果中,有几个关键字段值得关注:
winningPlan:这是 MongoDB 最终选择的执行计划。executionStats:包含了查询的执行统计信息,如executionTimeMillis(查询执行时间)、totalDocsExamined(扫描的文档数量)、nReturned(返回的文档数量)等。indexBounds:如果查询使用了索引,这里会显示索引的使用情况。
4. 示例
假设我们有一个 users 集合,并且我们想查看查询 { age: { $gt: 30 } } 的执行计划:
db.users.find({ age: { $gt: 30 } }).explain("executionStats")执行结果可能如下:
// www.javascriptcn.com code example
{
"queryPlanner": {
"plannerVersion": 1,
"namespace": "test.users",
"indexFilterSet": false,
"parsedQuery": { "age": { "$gt": 30 } },
"winningPlan": {
"stage": "COLLSCAN",
"filter": { "age": { "$gt": 30 } },
"direction": "forward"
},
"rejectedPlans": []
},
"executionStats": {
"executionSuccess": true,
"nReturned": 100,
"executionTimeMillis": 5,
"totalKeysExamined": 0,
"totalDocsExamined": 1000,
"executionStages": {
"stage": "COLLSCAN",
"filter": { "age": { "$gt": 30 } },
"nReturned": 100,
"executionTimeMillisEstimate": 5,
"works": 1001,
"advanced": 100,
"needTime": 900,
"needYield": 0,
"saveState": 1,
"restoreState": 1,
"isEOF": 1,
"direction": "forward",
"docsExamined": 1000
}
},
"serverInfo": {
"host": "localhost",
"port": 27017,
"version": "4.4.0",
"gitVersion": "some_git_version"
},
"ok": 1
}在这个例子中,winningPlan 显示查询使用了全表扫描(COLLSCAN),并且 executionStats 显示查询扫描了 1000 个文档,返回了 100 个文档,执行时间为 5 毫秒。
5. 优化建议
通过分析执行计划,你可以发现查询的性能瓶颈。例如,如果 totalDocsExamined 远大于 nReturned,说明查询可能没有使用合适的索引,导致扫描了过多的文档。这时,你可以考虑为查询字段创建索引来优化性能。