MongoDB 存储和优化系列三

2020-05-22 00:00:00 索引 查询 执行 计划 图标

上篇文章我们介绍了索引的基本概念,描述了不同类型索引的区别,工欲善其事,必先利其器,这篇文章,我们将展开介绍 explain 这个执行计划函数,进一步的了解Mongo的查询计划,来分析和诊断,提高查询的效率。

explain()是MongoDB的一个重要的查询诊断工具,这个函数能够提供大量与查询相关的信息,该函数会返回查询计划、执行状态、服务器信息,根据这些信息可以有针对性的对性能进行优化。

  • explain()函数
  • explain() 返回信息
  • explain() 使用示例

cursor.explain(verbosity)

  • verbose:{String},可选参数。指定冗长模式的解释输出,方式指定后会影响explain()的行为及输出信息。可选值有:"queryPlanner""executionStats""allPlansExecution",默认为"queryPlanner"

explain()返回信息

queryPlanner 包括以下值:

  1. queryPlanner.namespace「运行查询的指定命名空间」
  2. queryPlanner.indexFilterSet「表示MongoDB在查询中是否使用索引过滤」
  3. queryPlanner.winningPlan「由查询优化选择的计划」

winningPlan.stage「表示查询阶段的字符串」

winningPlan.inputStage「表示子过程的文档」

winningPlan.inputStages「表示子过程的文档数组」

queryPlanner.rejectedPlans「被查询优化备选并被拒绝的计划数组」

executionStats「被选中执行计划和被拒绝执行计划的详细说明」

queryPlanner.nReturned「匹配查询条件的文档数」

queryPlanner.executionTimeMillis「计划选择和查询执行所需的总时间(毫秒数)」

queryPlanner.totalKeysExamined「扫描的索引总数」

queryPlanner.totalDocsExamined「扫描的文档总数」

queryPlanner.executionStages「显示执行成功细节的查询阶段树」

executionStages.works「指定查询执行阶段执行的“工作单元”的数量」

executionStages.advanced「返回的中间结果数」

executionStages.needTime「未将中间结果推进到其父级的工作周期数」

executionStages.needYield「存储层要求查询系统产生的锁的次数」

executionStages.isEOF「指定执行阶段是否已到达流结束」


queryPlanner.allPlansExecution「包含在计划选择阶段期间捕获的部分,包括选择计划和拒绝计划」

serverInfo:「MongoDB实例的相关信息」

winningPlan.shards「包括每个访问片的queryPlanner和serverInfo的文档数组」

下图展示如何选择查询计划

执行 db.persons.find({age:10}).explain("executionStats")我们看具体的explain计划

/* 1 */
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "Performance.persons", --数据库名+集合的名称
        "indexFilterSet" : false,
        "parsedQuery" : {
            "age" : {
                "$eq" : 10.0 -- 生成原生的查询 {age:10}
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "age" : 1.0,
                    "name" : 1.0
                },
                "indexName" : "age_1_name_1",
                "isMultiKey" : false, -- 多Key索引
                "multiKeyPaths" : { -- 复合索引的Key Path 
                    "age" : [],
                    "name" : []
                },
                "isUnique" : false, -- 索引
                "isSparse" : false, -- 稀疏索引
                "isPartial" : false, -- 部分索引
                "indexVersion" : 2,
                "direction" : "forward", 
                "indexBounds" : { -- 索引的查询范围
                    "age" : [ 
                        "[10.0, 10.0]"
                    ],
                    "name" : [ 
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : []
    },
    "executionStats" : { -- 执行计划的统计
        "executionSuccess" : true,
        "nReturned" : 2, -- 查询得到的文档数目
        "executionTimeMillis" : 2, -- 查询消耗的毫秒数
        "totalKeysExamined" : 2, -- 索引扫描的数量
        "totalDocsExamined" : 2, -- 文档扫描的数量
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 2,
            "executionTimeMillisEstimate" : 0,
            "works" : 3, -- 工作单元
            "advanced" : 2, --返回的中间数
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1, -- 游标的末尾
            "invalidates" : 0,
            "docsExamined" : 2,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 2,
                "executionTimeMillisEstimate" : 0,
                "works" : 3,
                "advanced" : 2,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "age" : 1.0,
                    "name" : 1.0
                },
                "indexName" : "age_1_name_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "age" : [],
                    "name" : []
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "age" : [ 
                        "[10.0, 10.0]"
                    ],
                    "name" : [ 
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined" : 2,
                "seeks" : 1,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
    },
    "serverInfo" : { -- server information
        "host" : "bogon",
        "port" : 27017,
        "version" : "4.0.3",
        "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
    },
    "ok" : 1.0
}

相关文章