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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.deb包的安装方法

deb是Debian linux的安装格式&#xff0c;跟redhat的rpm非常相似&#xff0c;最基本的安装命令是&#xff1a; dpkg -i file.deb dpkg是Debian Package的简写&#xff0c;是为Debian专门开发的管理系统套件&#xff0c;方便软件的安装&#xff0c;更新和移除。所有源自Debian的…

html回复评论_3天内看了3000多篇《哈佛商业评论》,挑出来最有用的分享下

上次分享过一个工具&#xff1a;一键批量下载公众号历史消息&#xff08;后台回复001获取&#xff09;。我把《哈佛商业评论》的历史文章&#xff0c;全部爬了下来。该杂志被全球商业誉为“管理圣经”。我最感兴趣的一部分是&#xff1a;个人管理。先搜索关键词&#xff1a;&qu…

Java中的高性能库

越来越多的库被描述为高性能&#xff0c;并且有支持该要求的基准。 这是我所知道的选择。 Disruptor库 – http://code.google.com/p/disruptor/ LMAX旨在成为世界上最快的交易平台。 显然&#xff0c;为了实现这一目标&#xff0c;我们需要做一些特殊的事情&#xff0c;以通过…

Linux 命令行上执行多个命令(分隔符简介使用)

Linux 系统可以在一个命令行上执行多个命令&#xff0c;相应的命令行的分隔符简介及使用如下&#xff1a; ; 如果命令被分号(;)所分隔&#xff0c;那么命令会连续的执行下去&#xff0c;就算是错误的命令也会继续执行后面的命令。示例如下&#xff1a; ls /home/; ls /etc/i…

codeforces 732/D 二分

给出考试时间和考试需要准备的时间&#xff0c;问最早考完所有科目的时间 二分答案 NlogN 二分抄神犇的写法 感觉挺舒服的嘻嘻嘻 1 #include<bits/stdc.h>2 using namespace std;3 const int MAXN1e55;4 int N,M,d[MAXN],w[MAXN],cnt[MAXN];5 void read(int &x){6 …

XML基础(二)

XML命名规则&#xff1a; ①名称可以含字母、数字以及其他的字符 ②名称不能以数字或标点符号开始 ③名称不能以“xml”开始 ④名称不能包含空格 ⑤尽量避免"-", "." ,":"等字符 xml元素是可扩展的。 XML属性&#xff1a; 属性提供有关元素的额外…

NoSQLBooster for MongoDB 中跨库关联查询

​ 使用 MongoDB 是我们常常会遇到一些特殊的需求需要跨库关联查询&#xff0c;比如订单明细缺商品重量需要补商品重量&#xff0c;而商品重量数据又在商品库中&#xff0c;这事就需要跨库关联操作&#xff0c;示例代码如下&#xff1a; // 使用 order 库&#xff0c;注意语句…

网页版的svn怎样同步代码_学会使用Hdlbits网页版Verilog代码仿真验证平台

大家推荐一款网页版的 Verilog代码编辑仿真验证平台&#xff0c;这个平台是国外的一家开源FPGA学习网站&#xff0c;通过“https://hdlbits.01xz.net/wiki/Main_Page”地址链接进入网页&#xff0c;在该网页上可以进行Verilog代码的编写、综合&#xff0c;而且最后还能够仿真出…

遇到的零碎问题

Show()时&#xff0c;其他窗口仍可响应&#xff0c;ShowDialog()时其他窗口无响应。 在public Form1()中使用messagebox会先出现信息窗口&#xff0c;再显示主窗体&#xff0c;故考虑加入了start按钮。 play()会被打断&#xff0c;PlaySync&#xff08;&#xff09;会播放完再执…

Tomcat上具有JAX-WS的Web服务

让我们假设一家企业正在一个集中式系统中维护用户身份验证详细信息。 我们需要创建一个AuthenticationService&#xff0c;它将获取凭据&#xff0c;对其进行验证并返回状态。 其余的应用程序将使用AuthenticationService对用户进行身份验证。 创建AuthenticationService接口&a…

Python的下载及安装

1、官网下载地址&#xff1a;https://www.python.org/downloads/ 2、python设置环境变量&#xff1a; 在系统变量里添加Python的安装位置 3、在cmd里输入python里即可转载于:https://www.cnblogs.com/fun0623/p/5257573.html

MongoDB 字段拼接 $concat(aggregation)

$concat 拼接字符串操作&#xff0c;返回拼接后的字符串。语法格式如下&#xff1a; { $concat: [ <expression1>, <expression2>, ... ] }参数可以是任何有效的表达式&#xff0c;只要它们解析为字符串即可。 有关表达式的更多信息&#xff0c;请参阅表达式。 示…

cmake mysql 编译参数_Cmake-MySQL编译参数说明

Cmake-MySQL编译参数说明(来源于MySQL官方手册)https://dev.mysql.com/doc/refman/5.6/en/source-configuration-options.htmlFormats Description DefaultIntroduced Removed ##格式描述默认导入删除BUILD_CONFIG Use same build options as official releases ##b使用相同…

动态给H5页面绑定数据,基本万能无错误!

此为原创&#xff0c;转载请注明出处&#xff01; /* * 共通用绑定页面数据用方法 * * param bingData 需要绑定的数据 * * return 无 * */function commonBindData(bingData) { // 取得需绑定的json数据 var jsonArray eval("(" bingData ")"); // …

c语言函数---M

书画小说软件 制作更满意的读、更舒心的写、更轻松的公布最全古典小说网 由本软件公布所得main()主函数 每一C 程序都必须有一main()函数, 能够依据自己的爱好把它放在程序的某 个地方。有些程序猿把它放在最前面, 而还有一些程序猿把它放在最后面, 不管放 在哪个地方, 下面几…

使用Apache ActiveMQ的JMS开发基础

去年是我尝试JMS的时候。 背后的想法和概念让我有些困惑&#xff0c;但是当我知道它的用途后&#xff0c;我很快就掌握了它。 在本文中&#xff0c;我将展示使用Apache ActiveMQ作为后端使用Java开发简单的生产者/消费者的基础。 让我们首先从概念开始&#xff0c;这是一个简单…

vijos p1460——拉力赛

描述 车展结束后&#xff0c;游乐园决定举办一次盛大的山道拉力赛&#xff0c;平平和韵韵自然也要来参加大赛。 赛场上共有n个连通的计时点&#xff0c;n-1条赛道&#xff08;构成了一棵树&#xff09;。每个计时点的高度都不相同&#xff08;父结点的高度必然大于子结点&#…

mysql acid_Mysql中ACID的原理

原子性 (Atomicity)原子性是指一个事务是一个不可分割的工作单位&#xff0c;其中的操作要么都做&#xff0c;要么都不做。隔离性 (Isolation)隔离性是指多个事务并发执行的时候&#xff0c;事务内部的操作与其他事务是隔离的&#xff0c;并发执行的各个事务之间不能互相干扰…

MongoDB 自动删除集合中过期的数据——TTL索引

简介 ​ TTL (Time To Live, 有生命周期的) 索引是特殊单字段索引&#xff0c;MongoDB可以用来在一定时间后自动从集合中删除文档的特殊索引。 这对于某些类型的数据非常好&#xff0c;例如机器生成的事件数据&#xff0c;日志和会话信息&#xff0c;这些信息只需要在数据库中…

PLSQL 经常自动断开失去连接的解决过程

问题背景&#xff1a; 情况是这样的&#xff0c;很多开发同事的PLSQL上班时间开着8个小时&#xff0c;有时候他们出去抽烟后或者中午吃完饭&#xff0c;回来在PLSQL上面执行就报错无响应&#xff0c;然后卡住了半天动弹不了&#xff0c;非得重新登录plsql才生效&#xff0c;我猜…