在优化数据库时,可用使用命令 db.system.profile.find()
来找出哪些语句执行速度慢,接下来通常会加一些索引来加速查询,那么增加的索引对于执行语句是否起了作用,就需要使用查看下详细的查询计划来验证并根据情况修改索引或其他的设置。
那么读懂详细的查询计划就是一个比较关键了。
在执行类似于 db.collections.find().explain()
时只会输出(返回)
queryPlanner
与
serverInfo
而在执行类似于 db.collections.find().explain("executionStats")
时则会输出(返回)
queryPlanner
与
executionStats
与
serverInfo
queryPlanner模式下并不会去真正进行query语句查询,而是针对query语句进行执行计划分析并选出winning plan。
在非分片的集合中,explain会返回如下格式的信息
{
"queryPlanner" : {
"plannerVersion" : ,
"namespace" : ,
"indexFilterSet" : ,
"parsedQuery" : {
...
},
"winningPlan" : {
"stage" : ,
...
"inputStage" : {
"stage" : ,
...
"inputStage" : {
...
}
}
},
"rejectedPlans" : [
1>,
...
]
}
{
"queryPlanner" : {
...
"winningPlan" : {
...
"shards" : [
{
"shardName" : ,
for shard>,
for shard>
},
...
],
},
},
"executionStats" : {
...
"executionStages" : {
...
"shards" : [
{
"shardName" : ,
for shard>
},
...
]
},
"allPlansExecution" : [
{
"shardName" : ,
"allPlans" : [ ... ]
},
...
]
}
}
explain.executionStats.executionStages.shards :每个Shard上返回的executionStats 信息
一般返回的executionStats信息如下
"executionStats" : {
"executionSuccess" : ,
"nReturned" : ,
"executionTimeMillis" : ,
"totalKeysExamined" : ,
"totalDocsExamined" : ,
"executionStages" : {
"stage" :
"nReturned" : ,
"executionTimeMillisEstimate" : ,
"works" : ,
"advanced" : ,
"needTime" : ,
"needYield" : ,
"isEOF" : ,
...
"inputStage" : {
"stage" : ,
...
"nReturned" : ,
"executionTimeMillisEstimate" : ,
"keysExamined" : ,
"docsExamined" : ,
...
"inputStage" : {
...
}
}
},
"allPlansExecution" : [
{ },
{ },
...
]
}
executionStats.executionTimeMillis:指的是语句的执行整体时间
executionStats.executionStages.executionTimeMillis:该查询根据index去检索document获取nReturned条具体数据的时间
executionStats.executionStages.inputStage.executionTimeMillis:该查询扫描totalKeysExamined行index所用时间
nReturned=totalKeysExamined & totalDocsExamined=0
这表示:仅仅使用到了index,无需文档扫描,这是最理想状态
或者
nReturned=totalKeysExamined=totalDocsExamined(需要具体情况具体分析)
这表示:正常index利用,无多余index扫描与文档扫描。)
如果有sort的时候,为了使得sort不在内存中进行,我们可以在保证nReturned=totalDocsExamined的基础上,totalKeysExamined可以大于totalDocsExamined与nReturned,因为量级较大的时候内存排序非常消耗性能。
Stage的类型会影响到totalKeysExamined与totalDocsExamined
Fetch+IDHACK
Fetch+ixscan
Limit+(Fetch+ixscan)
PROJECTION+ixscan
SHARDING_FILTER+ixscan
不希望看到包含如下的stage
COLLSCAN(全表扫),SORT(使用sort但是无index),不合理的SKIP,SUBPLA(未用到index的$or)
对于count查询
希望看到COUNT_SCAN,而不是COUNT