MongoDB分析工具之一:explain()语句分析工具
explain(),语句分析工具
MongoDB 3.0之后,explain的返回与使用方法与之前版本有了很大的变化,介于3.0之后的优秀特色和我们目前所使用给的是3.0.7版本,本文仅针对MongoDB 3.0+的explain进行讨论。3.0+的explain有三种模式,分别是:queryPlanner、executionStats、allPlansExecution。现实开发中,常用的是executionStats模式,主要分析这种模式。
基本用法
先来看一个基本用法:
db.duan.find({x:1}).explain()
explain()添加不同参数
explain()也接收不同的参数,通过设置不同参数我们可以查看更详细的查询计划。
- queryPlanner:queryPlanner是默认参数,添加queryPlanner参数的查询结果就是我们上面表格中看到的查询结果。
- executionStats:executionStats会返回最佳执行计划的一些统计信息。
- allPlansExecution:allPlansExecution用来获取所有执行计划,结果参数基本与上文相同。
1、queryPlanner,这个是explain()默认参数
直接跟在find()函数后面,表示查看find()函数的执行计划,结果如下:
> db.duan.find({x:1}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "member_data.duan",
"indexFilterSet" : false,
"parsedQuery" : {
"x" : {
"$eq" : 1
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"x" : {
"$eq" : 1
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"serverInfo" : {
"host" : "localhost.localdomain",
"port" : 27017,
"version" : "4.0.6",
"gitVersion" : "caa42a1f75a56c7643d0b68d3880444375ec42e3"
},
"ok" : 1
}
>
返回结果包含两大块信息,一个是queryPlanner,即查询计划,还有一个是serverInfo,即MongoDB服务的一些信息。那么这里涉及到的参数比较多,queryPlanner结果参数说明如下:
| 参数 | 含义 |
| plannerVersion | 查询计划版本 |
| namespace | 要查询的集合(该值返回的是该query所查询的表) |
| indexFilterSet | 是否使用索引(针对该query是否有indexfilter) |
| parsedQuery | 查询条件,此处为x=1 |
| winningPlan | 最佳执行计划 |
| winningPlan.stage |
最优执行计划的stage(查询方式),常见的有: COLLSCAN/全表扫描:(应该知道就是CollectionScan,就是所谓的“集合扫描”,和mysql中table scan/heap scan类似,这个就是所谓的性能最烂最无奈的由来 )、 IXSCAN/索引扫描:(而是IndexScan,这就说明我们已经命中索引了)、 FETCH/根据索引去检索文档、SHARD_MERGE/合并分片结果、IDHACK/针对_id进行查询 |
| winningPlan.inputStage | 用来描述子stage,并且为其父stage提供文档和索引关键字。 |
| winningPlan.stage的child stage | 此处是IXSCAN,表示进行的是index scanning。 |
| winningPlan.keyPattern | 所扫描的index内容,此处是did:1,status:1,modify_time: -1与scid : 1 |
| winningPlan.indexName | winning plan所选用的index。 |
| winningPlan.isMultiKey | 是否是Multikey,此处返回是false,如果索引建立在array上,此处将是true。 |
| winningPlan.direction | 此query的查询顺序,此处是forward,如果用了.sort({modify_time:-1})将显示backward。 |
| filter | 过滤条件 |
| winningPlan.indexBounds | winningplan所扫描的索引范围,如果没有制定范围就是[MaxKey, MinKey],这主要是直接定位到mongodb的chunck中去查找数据,加快数据读取。 |
| rejectedPlans | 拒绝的执行计划(其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述) |
| serverInfo | MongoDB服务器信息 |
2、executionStats参数
executionStats会返回最佳执行计划的一些统计信息,如下:
> db.duan.find({x:1}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "member_data.duan",
"indexFilterSet" : false,
"parsedQuery" : {
"x" : {
"$eq" : 1
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"x" : {
"$eq" : 1
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 3,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"x" : {
"$eq" : 1
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 0,
"needTime" : 4,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 3
}
},
"serverInfo" : {
"host" : "localhost.localdomain",
"port" : 27017,
"version" : "4.0.6",
"gitVersion" : "caa42a1f75a56c7643d0b68d3880444375ec42e3"
},
"ok" : 1
}
>
| 参数 | 含义 |
| executionSuccess | 是否执行成功 |
| nReturned | 返回的结果数 |
| executionTimeMillis | 执行耗时 |
| totalKeysExamined | 索引扫描次数 |
| totalDocsExamined | 文档扫描次数 |
| executionStages | 这个分类下描述执行的状态 |
| stage | 扫描方式,具体可选值与上文的相同 |
| nReturned | 查询结果数量 |
| executionTimeMillisEstimate | 预估耗时 |
| works | 工作单元数,一个查询会分解成小的工作单元 |
| advanced | 优先返回的结果数 |
| docsExamined | 文档检查数目,与totalDocsExamined一致。检查了总共的个documents,而从返回上面的nReturne数量 |
常见用法:
第一层,executionTimeMillis
最为直观explain返回值是executionTimeMillis值,指的是我们这条语句的执行时间,这个值当然是希望越少越好。
其中有3个executionTimeMillis,分别是:
executionStats.executionTimeMillis
该query的整体查询时间。
executionStats.executionStages.executionTimeMillisEstimate
该查询根据index去检索document获得2001条数据的时间。
executionStats.executionStages.inputStage.executionTimeMillisEstimate
该查询扫描2001行index所用时间。
第二层,index与document扫描数与查询返回条目数
这个主要讨论3个返回项,nReturned、totalKeysExamined、totalDocsExamined,分别代表该条查询返回的条目、索引扫描条目、文档扫描条目。
这些都是直观地影响到executionTimeMillis,我们需要扫描的越少速度越快。
对于一个查询,我们最理想的状态是:
nReturned=totalKeysExamined=totalDocsExamined
第三层,stage状态分析
那么又是什么影响到了totalKeysExamined和totalDocsExamined?是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的返回
对于普通查询,我希望看到stage的组合(查询的时候尽可能用上索引):
Fetch+IDHACK
Fetch+ixscan
Limit+(Fetch+ixscan)
PROJECTION+ixscan
SHARDING_FITER+ixscan
COUNT_SCAN
SORT_KEY_GENERATOR
不希望看到包含如下的stage:
COLLSCAN(全表扫描),SORT(使用sort但是无index),不合理的SKIP,SUBPLA(未用到index的$or),COUNTSCAN(不使用index进行count)
3、allPlansExecution参数
示例:
> db.duan.find({x:1}).explain("allPlansExecution")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "member_data.duan",
"indexFilterSet" : false,
"parsedQuery" : {
"x" : {
"$eq" : 1
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"x" : {
"$eq" : 1
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 3,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"x" : {
"$eq" : 1
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 5,
"advanced" : 0,
"needTime" : 4,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward",
"docsExamined" : 3
},
"allPlansExecution" : [ ]
},
"serverInfo" : {
"host" : "localhost.localdomain",
"port" : 27017,
"version" : "4.0.6",
"gitVersion" : "caa42a1f75a56c7643d0b68d3880444375ec42e3"
},
"ok" : 1
}
>
聚合类的查询的explain()分析:
db.getCollection('my_order').explain().aggregate([
{$match: {"sender.id" : "8F8184E0ECF24B83980FE96357E7B746","status" : 1}},
{$group:{_id:"$sender.id",totalAmount:{$sum:"$amount"},quantity:{$sum:1}}}
])
结果示例说明:
{
"queryPlanner" : {
.........
},
"executionStats" : { //执行计划相关统计信息
"executionSuccess" : true, //执行成功的状态
"nReturned" : 1, //返回结果集数目
"executionTimeMillis" : 21896, //执行所需的时间,毫秒
"totalKeysExamined" : 0, //索引检查的时间
"totalDocsExamined" : 5000000, //检查文档总数
"executionStages" : {
"stage" : "COLLSCAN", //使用集合扫描方式
"filter" : { //过滤条件
"id" : {
"$eq" : 500
}
},
"nReturned" : 1, //返回结果集数目
"executionTimeMillisEstimate" : 19230, //预估的执行时间,毫秒
"works" : 5000002, //工作单元数,一个查询会被派生为一些小的工作单元
"advanced" : 1, //优先返回的结果数目
"needTime" : 5000000,
"needYield" : 0,
"saveState" : 39065,
"restoreState" : 39065,
"isEOF" : 1,
"invalidates" : 0,
"direction" : "forward", //方向
"docsExamined" : 5000000 //文档检查数目
}
},
"serverInfo" : {
...........
"ok" : 1
}
MongoDB分析工具之一:explain()语句分析工具的更多相关文章
- MySQL的explain语句分析
+----+-------------+-------+------------+------+---------------+-----+---------+------+------+------ ...
- oracle用EXPLAIN PLAN 分析SQL语句
EXPLAIN PLAN 是一个很好的分析SQL语句的工具,它甚至可以在不执行SQL的情况下分析语句. 通过分析,我们就可以知道ORACLE是怎么样连接表,使用什么方式扫描表(索引扫描或全表扫描)以及 ...
- tsql语句分析工具 转
一款好用且免费的语句分析工具 在调优过程中的查询语句优化阶段,分析语句的执行计划是必经之路,一款好的执行计划分析工具确实可以帮助我们事半功倍 一款名为“Plan Explorer“,自己用的挺爽,不私 ...
- LR工具使用之结果分析
LR工具使用之结果分析 1.启动loadrunner第三个控件Analysis分析测试结果.
- 想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研
想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研 http://blog.csdn.net/testing_is_believing/article/details/22 ...
- valgrind的callgrind工具进行多线程性能分析
1.http://valgrind.org/downloads/old.html 2.yum install valgrind Valgrind的主要作者Julian Seward刚获得了今年的Goo ...
- 并发工具CyclicBarrier源码分析及应用
本文首发于微信公众号[猿灯塔],转载引用请说明出处 今天呢!灯塔君跟大家讲: 并发工具CyclicBarrier源码分析及应用 一.CyclicBarrier简介 1.简介 CyclicBarri ...
- Delphi 开发手机 App 与其他工具之间的比较分析
写在前头 关于各种手机App开发的工具,从2010年前后到现在已经在很多不同的场合介绍过,在元智大学.中台科技大学.德霖科技大学等不同学校的讲座.课程当中,都有类似的主题,所以对我来说,这个主题属于驾 ...
- 5WHY分析法:一个问题分析与解决的工具
5WHY分析法很多做项目的都知道,但是却很少有人能用到实处,或者是灵活运用,所以今天小编又来翻一遍这个“旧账”,让大家更了解5WHY分析法. 什么是5WHY分析法? 所谓5why分析法,又称“5问法” ...
随机推荐
- ElasticSearch(二十六)修改分词器及定制自己的分词器
1.默认的分词器 standard 分词器 standard tokenizer:以单词边界进行切分standard token filter:什么都不做lowercase token filter: ...
- linux c编程:进程环境
一 进程终止: ⼀个进程可以登记若⼲个(具体⾃⼰验证⼀下)个函数,这些函数由exit⾃动调⽤,这些函数被称为终⽌处理函数, atexit函数可以登记这些函数. exit调⽤终⽌处理函数的顺序和atex ...
- 查看当前.net版本 cmd
reg query "HKLM\Software\Microsoft\NET Framework Setup\NDP" /s /v version | findstr /i ver ...
- 【SHARE】WEB前端学习资料
参考资料:https://github.com/karlhorky/learn-to-program 学习网站:http://www.codecademy.com/learn https://www. ...
- c++学习笔记(网上资料)
C++笔记 2007-3-22 1. 程序 —— 可执行文件,人发送给计算机的一组指令. 硬件指令是二进制, ...
- js之定时器
一.通过定时器我们可以间隔设定时间重复调用某个函数,利用这个特性,我们可以做很多事,例如,12306上的每间隔5秒查询自动查询一次余票,简单动画的实现等等 二.定时器的格式: 定时器有两种格式,分别是 ...
- ACM,我回来了!
经过两天的时间,到了家一趟! 我终于又重新回到ACM实验室了!,有点头晕啊!!!
- 《机器学习实战》学习笔记第十二章 —— FP-growth算法
主要内容: 一. FP-growth算法简介 二.构建FP树 三.从一颗FP树中挖掘频繁项集 一. FP-growth算法简介 1.上次提到可以用Apriori算法来提取频繁项集,但是Aprior ...
- BioNLP概述
BioNLP概述 工具: GENIA Tagger:GENIA Tagger是一个主要应用于生物医学文本领域的词性标注和浅层语法分析工具,GENIA Tagger在GENIA语料上的词性标记性能F-s ...
- pyqt5开发之俄罗斯方块
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial This is a Tetri ...