执行命令显示结果
执行db.student_exam.find({student_age: 15}).explain(‘allPlansExecution’);
{
"queryPlanner" : {
"plannerVersion" : 1.0,
"namespace" : "myproject.student_exam",
"indexFilterSet" : false,
"parsedQuery" : {
"student_age" : {
"$eq" : 15.0
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"student_age" : {
"$eq" : 15.0
}
},
"direction" : "forward"
},
"rejectedPlans" : [
]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 633.0,
"executionTimeMillis" : 5.0,
"totalKeysExamined" : 0.0,
"totalDocsExamined" : 10000.0,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"student_age" : {
"$eq" : 15.0
}
},
"nReturned" : 633.0,
"executionTimeMillisEstimate" : 0.0,
"works" : 10002.0,
"advanced" : 633.0,
"needTime" : 9368.0,
"needYield" : 0.0,
"saveState" : 78.0,
"restoreState" : 78.0,
"isEOF" : 1.0,
"invalidates" : 0.0,
"direction" : "forward",
"docsExamined" : 10000.0
},
"allPlansExecution" : [
]
},
"serverInfo" : {
"host" : "lijinzhuodeMacBook-Air.local",
"port" : 27017.0,
"version" : "3.6.13",
"gitVersion" : "db3c76679b7a3d9b443a0e1b3e45ed02b88c539f"
},
"ok" : 1.0
}
各字段含义
“plannerVersion” :版本
“namespace” : 数据库.集合
“indexFilterSet” : 是否使用索引
“parsedQuery” : 解析到的查询
“winningPlan” : 查询优化器针对该query所返回的最优执行计划的详细内容。
“stage” : 最优执行计划的阶段(stage有数个模式,将在后文中进行详解)
“direction” : 查询顺序forward表示升序,backward表示降序
“inputStage”: stage的child stage
“rejectedPlans” : 其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同。
“executionStats” : 执行状态
“executionSuccess” : 是否执行成功
“nReturned” : 返回文档数量
“executionTimeMillis” : 执行的时间(ms)
“totalKeysExamined” : 扫描索引的次数
“totalDocsExamined” : 扫描文档的次数
“executionStages” : 执行阶段
“advanced” : 优先返回给父阶段的中间结果集中文档个数
“needTime” : 9368.0,
“needYield” : 过程中被打断的次数
“saveState” : 保存状态
“restoreState” :
“isEOF” : 指定查询阶段是否已经结束
“invalidates” : 校验
“docsExamined” : 扫描文档次数,与totalDocsExamined相同
stage详解
stage状态分析
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索指定document
SHARD_MERGE 将各个分片返回数据进行merge
SORT 表明在内存中进行了排序(与老版本的scanAndOrder:true一致)
LIMIT 使用limit限制返回数
SKIP 使用skip进行跳过
IDHACK 针对_id进行查询
SHARDING_FILTER 通过mongos对分片数据进行查询
COUNT 利用db.coll.explain().count()之类进行count运算
COUNTSCAN count不使用Index进行count时的stage返回
COUNT_SCAN count使用了Index进行count时的stage返回
SUBPLA 未使用到索引的$or查询的stage返回
TEXT 使用全文索引进行查询时候的stage返回
PROJECTION 限定返回字段时候stage的返回
对于普通查询,我们最希望看到的组合有这些:
Fetch+IDHACK
Fetch+ixscan
Limit+(Fetch+ixscan)
PROJECTION+ixscan
SHARDING_FILTER+ixscan
不希望看到包含如下的stage:
COLLSCAN(全表扫)
SORT(使用sort但是无index)
SUBPLA(未用到index的$or)
对于count查询,希望看到的有:
COUNT_SCAN
不希望看到的有:
COUNTSCAN
注意: executionStages.Stage为Sort,在内存中进行排序了,这个在生产环境中尤其是在数据量较大的时候,是非常消耗性能的,这个千万不能忽视了,我们需要改进这个点。