MongoDB 3.0 执行计划(explain)分析详解


  • Lv 1

    1、概述:

    • MongoDB 3.0之后,explain的返回与使用方法较之前版本有了不少变化,鉴于3.0之后的优秀特色,本文仅针对MongoDB 3.0+的explain进行讨论。

    • 现版本explain有三种模式,分别如下: a.queryPlanner b.executionStats c.allPlansExecution

    • queryPlanner是现版本explain的默认模式,queryPlanner模式下并不会去真正进行query语句查询,而是针对query语句进行执行计划分析并选出winning Plan。

    2、我们先来看个例子,queryPlanner模式的各个返回意义

    {
            "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "game_db.game_user",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                            "w" : {
                                    "$eq" : 1
                            }
                    },
                    "winningPlan" : {
                            "stage" : "FETCH",
                            "inputStage" : {
                                    "stage" : "IXSCAN",
                                    "keyPattern" : {
                                            "w" : 1,
                                            "n" : 1
                                    },
                                    "indexName" : "w_1_n_1",
                                    "isMultiKey" : false,
                                    "direction" : "forward",
                                    "indexBounds" : {
                                            "w" : [
                                                    "[1.0, 1.0]"
                                            ],
                                            "n" : [
                                                    "[MinKey, MaxKey]"
                                            ]
                                    }
                            }
                    },
                    "rejectedPlans" : [
                            {
                                    "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]"
                                                    ]
                                            }
                                    }
                            }
                    ]
            },

    explain.queryPlanner.namespace 顾名思义,该值返回的是该query所查询的表。

    explain.queryPlanner.indexFilterSet 针对该query是否有indexfilter(会在后文进行详细解释)。

    explain.queryPlanner.winningPlan 查询优化器针对该query所返回的最优执行计划的详细内容。

    explain.queryPlanner.winningPlan.stage 最优执行计划的stage,这里返回是FETCH,可以理解为通过返回的index位置去检索具体的文档

    explain.queryPlanner.winningPlan.stage的child stage,此处是IXSCAN,表示进行的是index scanning。

    explain.queryPlanner.winningPlan.keyPattern 所扫描的index内容,此处是w:1与n:1。

    explain.queryPlanner.winningPlan.indexName winning plan所选用的index。

    explain.queryPlanner.winningPlan.isMultiKey 是否是Multikey,此处返回是false,如果索引建立在array上,此处将是true。

    explain.queryPlanner.winningPlan.direction 此query的查询顺序,此处是forward,如果用了.sort({w:-1})将显示backward。

    explain.queryPlanner.winningPlan.indexBounds winningplan所扫描的索引范围,此处查询条件是w:1,使用的index是w与n的联合索引,故w是[1.0,1.0]而n没有指定在查询条件中,故是[MinKey,MaxKey]。

    explain.queryPlanner.rejectedPlans 其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述。

    3、参数详解

    • 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的返回

    4、小结

    • 对于普通查询 我们最希望看到的组合有以下这些 Fetch+IDHACK; Fetch+ixscan; Limit+(Fetch+ixscan); PROJECTION+ixscan; SHARDING_FILTER+ixscan; 不希望看到的有以下这些 COLLSCAN(全表扫); SORT(使用sort但是无index); 不合理的SKIP; SUBPLA(未用到index的$or);
    • 对于count查询 我们希望看到的有:COUNT_SCAN;不希望看到的有:COUNTSCAN

    所以,当查询覆盖精确匹配,范围查询与排序的时候,精确匹配字段,排序字段,范围查询字段,这样的索引排序会更为高效。




登录后回复
 

与 萌阔论坛 的连接断开,我们正在尝试重连,请耐心等待