一架梯子,一头程序猿,仰望星空!
MongoDB入门教程 > 内容正文

MongoDB查询性能分析(explain)


本章介绍MongoDB查询性能分析,类似SQL的explain,MongoDB也支持explain分析查询语句的性能。

基本用法

调用explain函数,可以获取分析结果

// find方法分析结构
db.collection.find({}).explain();

// aggregate方法的分析结果
db.collection.explain().aggregate([]);

explain有三种模式:

  • queryPlanner (默认)
  • executionStats
  • allPlansExecution

说明:

  • 使用queryPlanner只列出所有可能执行的方案,不会执行实际的语句,显示已经胜出的方案winningPlan。
  • 使用executionStats只执行winningPlan方案,并输出结果。
  • 使用allPlansExecution执行所有的方案,并输出结果。

不用模式的用法

// executionStats 模式, 给explain函数传递参数即可
db.collection.find({}).explain('executionStats');

// allPlansExecution 模式
db.collection.find({}).explain('allPlansExecution');

explain内容解读

queryPlanner内容

下面内容是explain默认返回内容,忽略了非关键信息

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "test.orders",
        "indexFilterSet" : false, // 关键指标,有没有使用索引过滤数据
        "winningPlan" : {
            "stage" : "COLLSCAN",  // 关键指标,stage阶段名称。每个阶段都有每个阶段特有的信息,例如:COLLSCAN代表扫描整个集合内容
            "direction" : "forward"
        },
        "rejectedPlans" : [ ]
    }
    ...
}

stage阶段类型如下:

  • COLLSCAN:全表扫描
  • IXSCAN:索引扫描
  • FETCH:根据索引去检索指定document
  • SHARD_MERGE:将各个分片返回数据进行merge
  • SORT:表明在内存中进行了排序
  • 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的返回

executionStats内容

下面内容是executionStats模式返回内容,忽略了非关键信息

{
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 5,  // 返回文档数
        "executionTimeMillis" : 0, // 执行时间 
        "totalKeysExamined" : 0, // 扫描多少个索引
        "totalDocsExamined" : 5, // 总扫描文档数
        "executionStages" : {
            "stage" : "COLLSCAN", // 阶段类型, COLLSCAN全表扫描的意思
            "nReturned" : 5,
            "executionTimeMillisEstimate" : 0,
            "works" : 7,
            "advanced" : 5,
            "needTime" : 1,
            "needYield" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1,
            "direction" : "forward",
            "docsExamined" : 5
        }
    }
}

查询优化思路

  • 尽量使用索引
  • 扫描文档数越小越好