1.explain()方法
概念
通常来说,我们都需要对查询语句进行分析,来查看语句是否使用了索引还是全表扫描等。mysql中提供了EXLPAIN()关键字,而mongo中同样提供了explain()方法进行查询分析
语句
db.${collectionName}.find().explain(${分析方式})
其中分析方式参数可以缺省,具体参数介绍如下:
- queryPlanner:默认参数,缺省时默认为queryPlanner
- executionStats:会返回最佳执行计划的一些统计信息
-
2.explain()关键字段讲解
queryPlanner
使用: db.test.find({t:1}).explain()语句进行查询分析
返回字段具体如下:{
"queryPlanner":{
"plannerVersion":1,
"namespace":"db_test.test",
"indexFilterSet":false,
"parsedQuery":{
"t":{
"$eq":1
}
},
"queryHash":"E6282CBD",
"planCacheKey":"BD8C7DD3",
"winningPlan":{
"stage":"FETCH",
"inputStage":{
"stage":"IXSCAN",
"keyPattern":{
"t":1
},
"indexName":"t_1",
"isMultiKey":false,
"multiKeyPaths":{
"t":[
]
},
"isUnique":false,
"isSparse":false,
"isPartial":false,
"indexVersion":2,
"direction":"forward",
"indexBounds":{
"t":[
"[1.0, 1.0]"
]
}
}
},
"rejectedPlans":[
]
},
"serverInfo":{
"host":"instance-opiu1svq",
"port":27017,
"version":"4.4.15",
"gitVersion":"bc17cf2c788c5dda2801a090ea79da5ff7d5fac9"
},
"ok":1
}
winningPlan 属性是一个递归结构:winningPlan 指向获胜查询计划中的最后一个阶段,每个阶段都有一个描述前一阶段的 inputStage 属性。
在上述计划中,有两个阶段:IXSCAN 和 FETCH(从递归最底层往外看)。这意味着第一个 MongoDB 使用 { t: 1 } 索引来确定哪些文档与查询匹配,然后获取各个文档
重点关注stage字段 如果stage字段为”IXSCAN”,代表使用了索引。
如果stage字段为”COLLSCAN”,代表扫描了整个集合进行文档查询
executionStats
使用: db.test.find({t:1}).explain(“executionStats”)语句进行查询分析
返回字段具体如下:{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db_test.test",
"indexFilterSet" : false,
"parsedQuery" : {
"t" : {
"$eq" : 1
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"t" : 1
},
"indexName" : "t_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"t" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"t" : [
"[1.0, 1.0]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 0,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0,
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"t" : 1
},
"indexName" : "t_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"t" : [ ]
},total
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"t" : [
"[1.0, 1.0]"
]
},
"keysExamined" : 1,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
},
"serverInfo" : {
"host" : "instance-opiu1svq",
"port" : 27017,
"version" : "4.4.15",
"gitVersion" : "bc17cf2c788c5dda2801a090ea79da5ff7d5fac9"
},
"ok" : 1
}
如图,多了一个executionStats属性。重点关注executionTimeMillis字段以及totalDocsExamined字段
executionTimeMillis:mongo服务器执行查询花费的时间,但是并不包括接受命令以及返回命令的网络耗时。因此该字段时间短,不代表整体查询时间短
totalDocsExamined:mongo服务器查询结果必须检索的文档数量。如果触发了覆盖索引查询,那么这个字段=0
allPlansExecution
allPlansExecution返回的字段与executionStats一致,这里不做过多描述
3.hint()方法
概念
$hint 运算符(也叫“强制查询优化器”)能够使用指定的索引来进行查询,以此来测试查询的性能。
如果想要测试具有不同索引的查询性能时,此功能特别有用。
在 mongo shell 中可以使用 $hint 的辅助方法 hint() 来使用此功能语句
使用hint强制指定索引查询:db.${collectionName}.hint({{$indexName:1/-1},…})
- 使用hint强制指定索引查询进行分析:db.${collectionName}.hint({{$indexName:1/-1},…}).explain()