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()
