持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
介绍
explain 是做什么的?如何工作?
分析查询的过程中,执行的最佳情况
- 可以查询是否使用了期望的索引
- 索引是否提供了排序
- 可以提供多种索引的执行计划
- 统计查询过程中的信息
Mongodb 提供了explain 命令,可以帮我们评估指定查询(querymodel)的执行计划,根据实际情况调整,从而提高查询效率。
如何使用?
我们只需要将explain()方法附加到查询末尾
db.<collection>.find().explain(<verbose>)
verbose可选参数,表示执行计划的输出模式,默认queryPlanner。
然后,这种形式有一些限制,假如,存在更复杂的命令,或者需要重新运行多个查询,建议我们创建一个可解释对象,重复使用。
exp = db.<collection>.explain()
exp.find()
这样我们可以解释多个查询,非常方便。
模式
explain 共提供了3种模式,以便我们在不同情况下使用。
queryPlanner模式
执行计划的详细信息,包括查询计划、集合信息、查询条件、最佳执行计划、查询方式和Mongodb服务信息等。
"queryPlanner" : {
"plannerVersion" : <int>,
"namespace" : <string>,
"indexFilterSet" : <boolean>,
"parsedQuery" : {
...
},
"queryHash" : <hexadecimal string>,
"planCacheKey" : <hexadecimal string>,
"optimizedPipeline" : <boolean>, // Starting in MongoDB 4.2, only appears if true
"winningPlan" : {
"stage" : <STAGE1>,
...
"inputStage" : {
"stage" : <STAGE2>,
...
"inputStage" : {
...
}
}
},
"rejectedPlans" : [
<candidate plan 1>,
...
]
}
| key | 描述 |
|---|---|
queryPlanner.planerVersion | 执行计划的版本 |
queryPlanner.namespace | 命名空间,包含数据库名称和集合名称(<database>.<collection>.) |
queryPlanner.indexFilterSet | 是否使用了索引 |
queryPlanner.parsedQuery | 查询条件 |
queryPlanner.queryHash | 查询的一个哈希值,帮助职别具有相同查询的慢查询,这块不同擦护心发生哈希冲突的情况可能性很小。 |
queryPlanner.planCacheKey | 与查询关联的计划缓存键的哈希 |
queryPlanner.optimizedPipeline | 表示整个聚合管道操作是否被优化掉,一些简单的查询,会被优化,而不是使用聚合来做。比如:管道中只有一个$match。 |
queryPlanner.winningPlan | 选择的执行计划,将以树的形式展现;每一个阶段可以有一个inputStage ,如果阶段有多个子阶段,则会返回多个。 |
queryPlanner.winningPlan.stage | 表示当前阶段的查询方式 |
queryPlanner.winningPlan.inputStage | 子阶段的执行情况,子阶段向父阶段会提供文档或索引键。 |
queryPlanner.winningPlan.inputStages | 一组子阶段的执行情况 |
queryPlanner.rejectedPlans | 拒绝的执行计划 |
exectionStats模式和allPlansExecution 模式
都可以返回最佳的执行计划,allPlansExecution模式相比较多了其他的执行计划。
executionStats: {
executionSuccess: <boolean>,
nReturned: <int>,
executionTimeMillis: <int>,
totalKeysExamined: <int>,
totalDocsExamined: <int>,
executionStages: {
stage: <STAGE1>
nReturned: <int>,
executionTimeMillisEstimate: <int>,
opens: <int>, // Starting in MongoDB 5.1
closes: <int>, // Starting in MongoDB 5.1
works: <int>,
advanced: <int>,
needTime: <int>,
needYield: <int>,
saveState: <int>,
restoreState: <int>,
isEOF: <boolean>,
...
inputStage: {
stage: <STAGE2>,
nReturned: <int>,
...
numReads: <int>, // Starting in MongoDB 5.1
...
executionTimeMillisEstimate: <int>,
...
inputStage: {
...
}
}
},
allPlansExecution: [
{
nReturned: <int>,
executionTimeMillisEstimate: <int>,
totalKeysExamined: <int>,
totalDocsExamined:<int>,
executionStages: {
stage: <STAGEA>,
nReturned: <int>,
executionTimeMillisEstimate: <int>,
...
inputStage: {
stage: <STAGEB>,
...
inputStage: {
...
}
}
}
},
...
]
}
| key | 描述 |
|---|---|
executionStats.nReturned | 符合条件的文档数,旧版本中的:n |
executionStats.executionTimeMillis | 解释和查询执行的总时间,单位:毫秒,旧版本的millis |
executionStats.totalKeysExamined | 扫描索引键数目,旧版本的nscanned |
executionStats.totalDocsExamined | 扫描的文档数目。不代表返回的文档数,而且并不是只扫描一次,可能在不同的步骤扫描多次。 |
executionStats.executionStages | 执行情况 |
executionStats.executionStages.executionTimeMillisEstimate | 查询的一个预估时间,单位:毫秒 |
executionStats.executionStages.opens | 从 MongoDB 5.1 开始,在查询执行期间打开阶段的次数。 |
executionStats.executionStages.closes | 从 MongoDB 5.1 开始,在查询执行期间关闭阶段的次数。 |
executionStats.executionStages.works | 查询阶段中执行的“工作单元”数量,可能包括索引键、文档等。 |
executionStats.executionStages.saveState | 查询阶段暂停处理并保存起当前执行状态的次数,例如准备释放其锁的次数 |
executionStats.executionStages.restoreState | 查询阶段恢复保存的执行状态的次数,例如在恢复它之前产生的锁之后。 |
executionStats.executionStages.isEOF | 执行阶段是否到达流的尾部:1或true:表示到达,即一次执行完成0或false:表示未到达,该阶段可能仍有结果要返回。例如,考虑一个具有限制的查询,其执行阶段由一个阶段组成,该LIMIT阶段的输入阶段IXSCAN为 。如果查询返回超过指定限制,该LIMIT阶段将报告isEOF: 1,但其底层IXSCAN阶段将报告isEOF: 0。 |
explain.executionStats.executionStages.inputStage | 描述子文档 |
executionStats.allPlansExecution | 所有的执行计划。 |