MongoDB 提供 db.collection.explain(), cursort.explain() 及 explain 命令获取查询计划及查询计划执行统计信息。

explain 结果将查询计划以阶段树的形式呈现。 每个阶段将其结果(文档或索引键)传递给父节点。 叶节点访问集合或索引。 中间节点操纵由子节点产生的文档或索引键。 根节点是MongoDB从中派生结果集的最后阶段。

阶段操作描述,例:

  • COLLSCAN 集合扫描
  • IXSCAN 索引扫描
  • FETCH 检出文档
  • SHARD_MERGE 合并分片中结果
  • SHARDING_FILTER 分片中过滤掉孤立文档
  • LIMIT 使用limit 限制返回数
  • PROJECTION 使用 skip 进行跳过
  • IDHACK 针对_id进行查询
  • COUNT 利用db.coll.explain().count()之类进行count运算
  • COUNTSCAN count不使用Index进行count时的stage返回
  • COUNT_SCAN count使用了Index进行count时的stage返回
  • SUBPLA 未使用到索引的$or查询的stage返回
  • TEXT 使用全文索引进行查询时候的stage返回
  • PROJECTION 限定返回字段时候stage的返回

explain 操作返回结果详解

queryPlanner

queryPlanner 显示的是被查询优化器选择出来的查询计划。

以下未分片集合 explain 操作结果如下:

{"queryPlanner" : {"plannerVersion" : <int>,"namespace" : <string>,"indexFilterSet" : <boolean>,"parsedQuery" : {...},"winningPlan" : {"stage" : <STAGE1>,..."inputStage" : {"stage" : <STAGE2>,..."inputStage" : {...}}},"rejectedPlans" : [<candidate plan 1>,...]}
  • queryPlanner.namespace 一个字符串,指定运行查询的命名空间(即.)。
  • queryPlanner.indexFilterSet boolan值,表示MongoDB 对于此query shape 是否使用了索引过滤器。
  • queryPlanner.winningPlan 文档类型,详细显示查询优化程序选择的查询计划。
    • winningPlan.stage 阶段名称。每个阶段都有每个阶段特有的信息。 例如,IXSCAN 阶段将包括索引边界以及特定于索引扫描的其他数据。 如果阶段具有子阶段或多个子阶段,则阶段将具有inputStage 或 inputStages。
    • winningPlan.inputStage 描述子阶段的文档。它为其父级提供文档或索引键。 如果父级只有一个子级,则该字段存在。
    • winningPlan.inputStages 描述子阶段的数组。子阶段为父阶段提供文档或索引键。 如果父级具有多个子节点,则该字段存在。 例如,$or 表达式或索引交集的阶段消耗来自多个源的输入。
  • queryPlanner.rejectedPlans 查询优化器考虑和拒绝的候选计划数组。 如果没有其他候选计划,则该数组可以为空。

对于分片集合,获胜计划包括分每个访问的分片的计划信息数组。

executionStats

executionStats 返回的是获胜计划执行相关信息。必须在 executionStats 或 allPlansExecution 详细模式下运行explain才显示executionStats 相关信息。

要捕获选择执行计划期间执行相关信息,必须使用 allPlansExecution 模式运行。

executionStats 模式 explain 实例:

db.products.explain("executionStats").find({ quantity: { $gt: 50 }, category: "apparel" }
)

allPlansExecution 模式 explain 实例:

db.products.explain("allPlansExecution").update({ quantity: { $lt: 1000}, category: "apparel" },{ $set: { reorder: true } }
)

以下未分片集合 explain 操作结果如下:

"executionStats" : {"executionSuccess" : <boolean>,"nReturned" : <int>,"executionTimeMillis" : <int>,"totalKeysExamined" : <int>,"totalDocsExamined" : <int>,"executionStages" : {"stage" : <STAGE1>"nReturned" : <int>,"executionTimeMillisEstimate" : <int>,"works" : <int>,"advanced" : <int>,"needTime" : <int>,"needYield" : <int>,"isEOF" : <boolean>,..."inputStage" : {"stage" : <STAGE2>,..."nReturned" : <int>,"executionTimeMillisEstimate" : <int>,"keysExamined" : <int>,"docsExamined" : <int>,..."inputStage" : {...}}},"allPlansExecution" : [{ <partial executionStats1> },{ <partial executionStats2> },...]
}
  • executionStats 描述获胜计划完整的查询执行信息。 对于写入操作,是指将要执行修改的信息,但不会真实修改数据库。

    • executionStats.nReturned 查询条件匹配到的文档数量。
    • executionStats.executionTimeMillis 查询计划选择和查询执行所需的总时间(以毫秒为单位)。executionTimeMillis 对应于早期版本的MongoDB中cursor.explain() 返回的millis字段。
    • executionStats.totalKeysExamined 扫描的索引条目数。totalKeysExamined 对应于早期版本的MongoDB中cursor.explain() 返回的 nscanned字段。
    • executionStats.totalDocsExamined 扫描的文档数。totalDocsExamined 对应于早期版本的MongoDB中cursor.explain() 返回的 nscannedObjects字段。
    • executionStats.executionStages 阶段树形式展示获胜计划完整的执行信息。即,一个阶段可以有一个inputStage或多个inputStages。
      • executionStats.executionStages.works 查询执行阶段执行的“工作单元”的数量。 查询执行阶段将其工作分为小单元。 “工作单位”可能包括检查单个索引键,从集合中提取单个文档,将投影应用于单个文档或执行内部记账。

      • executionStats.executionStages.advanced 返回到父阶段的结果数。

      • executionStats.executionStages.needTime 未将中间结果返回给其父级的工作循环数。 例如,索引扫描阶段可以花费一个工作周期来寻找索引中的新位置而不是返回索引关键字; 这个工作周期将计入explain.executionStats.executionStages.needTime而不是explain.executionStats.executionStages.advanced。

      • executionStats.executionStages.needYield 存储层请求查询系统产生锁定的次数。

      • executionStats.executionStages.isEOF 执行阶段是否已到达流的结尾:

        • 如果为true或1,则执行阶段已到达流末尾。
        • 如果为false或0,则阶段可能仍会返回结果。 例如,有限制的查询,其执行阶段包含LIMIT阶段,其中查询的输入阶段为IXSCAN。 如果查询返回超过指定的限制,LIMIT阶段将报告isEOF:1,但其基础IXSCAN阶段将报告isEOF:0。
      • executionStats.executionStages.inputStage.keysExamined 对于扫描索引的查询执行阶段(例如IXSCAN),keysExamined是在索引扫描过程中检查的入站和越界键的总数。 如果索引扫描由单个连续范围的键组成,则只需要检查入站键。 如果索引边界由若干键范围组成,则索引扫描执行过程可以检查越界键,以便从一个范围的末尾跳到下一个范围的开头。

        考虑以下示例,集合包含字段x值为1到100的100个文档,其中索引字段为x:

        for(var x=1;x<=100;x++){db.keys.insert({x:x});
        }
        db.keys.ensureIndex({x:1});
        db.keys.find( { x : { $in : [ 3, 4, 50, 74, 75, 90 ] } } ).explain( "executionStats" )
        

        该查询将扫描键3和4.然后它将扫描键5,检测它是否超出界限,并跳到下一个键50。

        继续该过程,查询扫描键3,4,5,50,51,74,75,76,90和91.键5,51,76和91是仍在检查的越界键。 keysExamined的值为10。

      • executionStats.executionStages.inputStage.docsExamined 在查询执行阶段扫描的文档数。

      • executionStats.allPlansExecution 包含在计划选择阶段为获胜和拒绝计划捕获的部分执行信息。 仅当explain在allPlansExecution详细模式下运行时,该字段才会出现。

serverInfo

对于未分片的集合,MongoDB实例explain返回以下信息:

"serverInfo" : {"host" : <string>,"port" : <int>,"version" : <string>,"gitVersion" : <string>
}

对于分片集合,explain返回每个访问的分片的serverInfo。

Sharded Collection

对于分片集合,explain在shards字段中返回每个访问的分片的核心查询规划器和服务器信息:

{"queryPlanner" : {..."winningPlan" : {..."shards" : [{"shardName" : <shard>,<queryPlanner information for shard>,<serverInfo for shard>},...],},},"executionStats" : {..."executionStages" : {..."shards" : [{"shardName" : <shard>,<executionStats for shard>},...]},"allPlansExecution" : [{"shardName" : <string>,"allPlans" : [ ... ]},...]}
}
  • queryPlanner.winningPlan.shards 每个访问分片的queryPlanner和serverInfo的文档数组。
  • executionStats.executionStages.shards 包含每个访问分片的executionStats的文档数组。

兼容性的修改

在 3.0 版本中的修改。

explain 结果的格式和字段与以前的版本相比有所变化。 以下列出了一些主要差异。

集合扫描 VS 索引使用

如果查询计划程序选择了集合扫描,则说明结果包括COLLSCAN阶段。

如果查询计划程序选择索引,则说明结果包括IXSCAN阶段。 该阶段包括诸如索引key的匹配,遍历方向和索引边界之类的信息。

在早期版本的MongoDB中,cursor.explain() 返回了光标字段,其值为:

用于集合扫描的BasicCursor,以及索引扫描的BtreeCursor <索引名称> [<方向>]。

覆盖查询

当索引覆盖查询时,MongoDB可以匹配查询条件并仅使用索引键返回结果; 即MongoDB不需要检查集合中的文档以返回结果。

当索引覆盖查询时,解释结果的IXSCAN阶段不是FETCH阶段的后代,而在executionStats中,totalDocsExamined为0。

在早期版本的MongoDB中,cursor.explain() 返回indexOnly字段以指示索引是否覆盖了查询。

索引交叉

对于索引交集计划,结果将包括AND_SORTED阶段或AND_HASH阶段,其中包含详细说明索引的inputStages数组; 例如。:

{"stage" : "AND_SORTED","inputStages" : [{"stage" : "IXSCAN",...},{"stage" : "IXSCAN",...}]
}

在以前版本的MongoDB中,cursor.explain() 返回了游标字段,其中包含索引交叉点的复杂计划。

$or 表达式

如果MongoDB使用$or 表达式的索引,则结果将包含OR阶段,其中包含详细说明索引的inputStages数组; 例如。:

{"stage" : "OR","inputStages" : [{"stage" : "IXSCAN",...},{"stage" : "IXSCAN",...},...]
}

在早期版本的MongoDB中,cursor.explain() 返回了详细索引的子句数组。

Sort 阶段

如果MongoDB可以使用索引扫描来获取请求的排序顺序,则结果将不包括SORT阶段。 否则,如果MongoDB无法使用索引进行排序,则解释结果将包括SORT阶段。

在MongoDB 3.0之前,cursor.explain() 返回scanAndOrder字段以指定MongoDB是否可以使用索引顺序返回排序结果。

总结

explain 希望看到的阶段

Fetch+IDHACK

Fetch+ixscan

Limit+(Fetch+ixscan)

PROJECTION+ixscan

SHARDING_FILTER+ixscan

COUNT_SCAN

explain 不希望看到的阶段

COLLSCAN(全表扫描),

SORT(使用sort但是无index),

不合理的SKIP,

SUBPLA(未用到index的$or),

COUNTSCAN

来自个人博客:学习园
http://www.xuexiyuan.cn/article/detail/179.html

MongoDB查询性能分析—— explain 操作返回结果详解相关推荐

  1. Android Studio CPU profiler性能分析工具介绍和使用详解

    Android Studio CPU profiler性能分析工具介绍和使用详解 CPU profiler介绍 Android Studio CPU 性能剖析器可实时检查应用的 CPU 使用率和线程活 ...

  2. MongoDB查询性能分析

    explain()方法能够提供大量与查询相关的信息.对于速度比较慢的查询来说,它是最重要的性能分析工具之一.通过查看一个查询的explain()输出信息,可以知道查询使用了哪个索引,以及是如何使用的. ...

  3. 性能分析工作strace命令用法详解及使用例子

    1 功能说明 strace 命令是一种强大的工具, 能够显示任何由用户空间程式发出的系统调用. strace 显示这些调用的参数并返回符号形式的值. strace 从内核接收信息, 而且无需以任何特别 ...

  4. PHP性能分析工具xhprof 参数简介详解

    Function Name:方法名称. Calls:方法被调用的次数. Calls%:方法调用次数在同级方法总数调用次数中所占的百分比. Incl.Wall Time(microsec):方法执行花费 ...

  5. MySQL02--高级(BTreeB+Tree、聚簇索引非聚簇索引、性能分析(Explain)、索引、sql优化)

    1.MySQL架构 2.sql 执行顺序: FROM <LEFT_TABLE> ON <JOIN_CONDITION> <JOIN_TYPR> JOIN <R ...

  6. MySQL简单查询性能分析

    MySQL简单查询性能分析  建立如此结构的数据表,并插入110万条随机记录,进行查询性能测试.   插入110万条随机记录后,数据表的大小为102MB. 现在使用phpMyAdmin自带的SQL查询 ...

  7. mysql执行计划性能_MySQL SQL性能分析Explain执行计划

    一. 执行计划返回信息详解 ①. 执行计划所含字段 输出列含义id查询标识 select_type查询类型 table查询涉及的表 partitions匹配到的分区信息 type连接类型 possib ...

  8. pdo mysql 绑定查询_php mysql PDO 查询操作的实例详解

    php mysql PDO 查询操作的实例详解 php mysql PDO 查询操作的实例详解 这篇文章主要介绍了php mysql PDO 查询操作的实例详解的相关资料,希望通过本文能帮助到大家,需 ...

  9. php mysql PDO 查询操作的实例详解

    php mysql PDO 查询操作的实例详解 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...

最新文章

  1. SQL Server-事务处理(Tansaction)与锁(Lock)
  2. WPF中引入外部资源
  3. 网易云音乐下线所有明星艺人榜单,对数字专辑及单曲限购
  4. 典型测试错误(英中文对照)
  5. 单总线CPU微程序条件判别测试逻辑
  6. PHP LOL接口,电竞数据API接口|英雄联盟lol|联赛统计|API调用示例代码
  7. 无法加载文件 C:\Users\*****\AppData\Roaming\npm\cnpm.ps1,因为在此系统上禁止运行脚本。——VScode终端问题解决办法
  8. 算法设计与分析第十三次作业
  9. Tika 1.16架构及核心模块
  10. 怎么处理视频声音变声?视频声音变声处理软件哪个好?
  11. 【ubuntu】fatal: detected dubious ownership in repository at ...
  12. 解决小米远程管理下电脑出现ftp文件错误提示
  13. Android Camera HAL3 -SessionParameter
  14. 【计算机网络】DNS域名系统
  15. 从一次“并发修改字段业务”引出多版本并发控制与InnoDB锁
  16. Arjian不是Arjan:樱桃司这八年
  17. arcgis10.2破解版教程(中文版)
  18. 解决问题黄金三步:定义问题—分解问题—归类分组
  19. HCIP-DATACOM-带解析-1-50题(821)
  20. lzb有博客了233

热门文章

  1. 华为微型计算机b515,华为MateStation B515台式机曝光:五种配置
  2. oracle 数据执行计划,Oracle 常见的执行计划步骤(explain结果的Description数据参考)...
  3. 怎样打开计算机音频服务器,win10系统音频服务器未运行的修复步骤
  4. 【APICloud系列|38】 微信登录分享、QQ登录分享实现方法
  5. 微信提交表单到服务器,微信小程序页面表单如何跟图片一起上传服务器
  6. strspn php,php返回在字符串中包含 charlist 参数中指定的字符数目的函数strspn()
  7. line-height 属性
  8. setTimeout(fn,0)
  9. ArcGIS中的WKID(转)
  10. CSS3 Filter详解(改变模糊度 亮度 透明度等方法)