我的专栏地址:我的segmentfault,欢迎浏览一、执行计划介绍MongoDB 3.0之后,explain的返回与使用方法与之前版本有了不少变化,介于3.0之后的优秀特色,本文仅针对MongoDB 3.0+的explain进行讨论。现版本explain有三种模式,分别如下:queryPlannerexecutionStatsallPlansExecution其中 queryPlanner 是现版本explain的默认模式,queryPlanner模式下并不会去真正进行query语句查询,而是针对query语句进行执行计划分析并选出winning plan。举个执行计划的命令例子:db.usertable.find({“w”: 1}).explain(“queryPlanner”)举个执行计划响应结果的例子:{ “queryPlanner”:{ “plannerVersion”:1, “namespace”:“game_db.game_user”, #该值返回的是该query所查询的表 “indexFilterSet”:false, #是否应用了index filter “parsedQuery”:{ #查询条件 “w”:{ “$eq”:1 } }, “winningPlan”:{ #查询优化器针对该query所返回的最优执行计划的详细内容 “stage”:“FETCH”, #最优执行计划的stage,这里返回是FETCH,可以理解为通过返回的index位置去检索具体的文档 “inputStage”:{ # #explain.queryPlanner.winningPlan.stage的child stage,此处是IXSCAN,表示进行的是index scanning。 “stage”:“IXSCAN”, #索引查找 “keyPattern”:{ #所扫描的index内容,此处是w:1与n:1。 “w”:1, “n”:1 }, “indexName”:“w_1_n_1”, #winning plan所选用的index。 “isMultiKey”:false, #本次查询是否使用了多键、复合索引 “direction”:“forward”, #此query的查询顺序,此处是forward,如果用了.sort({w:-1})将显示backward。 “indexBounds”:{ #winningplan所扫描的索引范围,此处查询条件是w:1,使用的index是w与n的联合索引,故w是[1.0,1.0]而n没有指定在查询条件中,故是[MinKey,MaxKey]。 “w”:[ “[1.0, 1.0]” ], “n”:[ “[MinKey, MaxKey]” ] } } }, “rejectedPlans”:[ #其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述。 { “stage”:“FETCH”, “inputStage”:{ “stage”:“IXSCAN”, “keyPattern”:{ “w”:1, “v”:1 }, “indexName”:“w_1_v_1”, “isMultiKey”:false, “direction”:“forward”, “indexBounds”:{ “w”:[ “[1.0, 1.0]” ], “v”:[ “[MinKey, MaxKey]” ] } } } ] }, “serverInfo” : { “host” : “ALI-SZ-VT-TEST001”, “port” : 27017, “version” : “4.0.5”, “gitVersion” : “3739429dd92b92d1b0ab120911a23d50bf03c412” }, “ok” : 1}二、queryPlanner学习2.1 Stage的意义如explain.queryPlanner.winningPlan.stageexplain.queryPlanner.winningPlan.inputStage**等。stage/inputStage值值的意义COLLSCAN全表扫描IXSCAN索引扫描FETCH根据索引去检索指定documentSHARD_MERGE将各个分片返回数据进行mergeSORT表明在内存中进行了排序(与老版本的scanAndOrder:true一致)LIMIT使用limit限制返回数SKIP使用skip进行跳过IDHACK针对_id进行查询SHARDING_FILTER通过mongos对分片数据进行查询COUNT利用db.coll.explain().count()之类进行count运算COUNTSCANcount不使用用Index进行count时的stage返回COUNT_SCANcount使用了Index进行count时的stage返回SUBPLA未使用到索引的$or查询的stage返回TEXT使用全文索引进行查询时候的stage返回PROJECTION限定返回字段时候stage的返回 2.2一个stage/inputStage的特点执行一:db.usertable.find({“field0”: “use”}).explain(“queryPlanner”){ … “winningPlan” : { “stage” : “COLLSCAN”, “filter” : { “field0” : { “$eq” : “use” } }, “direction” : “forward” }, …}执行二:db.usertable.find({“field0”: “use”}).limit(1).explain(“queryPlanner”){ … “winningPlan” : { “stage” : “LIMIT”, “limitAmount” : 1, “inputStage” : { “stage” : “COLLSCAN”, “filter” : { “field0” : { “$eq” : “use” } }, “direction” : “forward” } }, …}执行二在执行一的基础上增加了 limit限掉, queryPlanner由 stage(COLLSCAN) 变成了 stage(LIMIT)、inputStage.stage(COLLSCAN)。说明在判断queryPlanner是否达到用户想要的效果要对 stageinputStage.stag综合考虑。参考文章:MongoDB干货系列2-MongoDB执行计划分析详解 http://www.mongoing.com/eshu_explain2官方文档: https://docs.mongodb.com/manual/tutorial/analyze-query-plan/