Mongo explain()使用
explain作用
在通过mongo语句进行查询时,如果查询速度过慢,可以用此方法 显示 mongo在查询过程中的查询计划,是否使用索引,以及 查询,并返回了多少行 等等信息 帮助开发人员 在进一步优化之前,提供准确的信息;
explain方法参数
verbosity参数,值如下(其实就是返回值 显示信息多少的问题)
- queryPlanner 或 0/false 默认值; 返回值只返回 queryPlanner和serverInfo
- executionStats 返回值返回 详细的执行状态相关信息,如 扫描了多少行,耗时多久等等;
- allPlansExecution 或 1(非0的值都行) /true 返回值在 executionStats 字典中多了allPlansExecution字段;
explain方法返回值
查询语句如下:
db.collection_name.find({index_key_name:1}).explain(1)
返回示例如下:
{"queryPlanner": { # 查询计划"plannerVersion": NumberInt("1"), # 计划版本"namespace": "db_name.collection_name", # 命名空间,作用于哪个库的哪个集合"indexFilterSet": false, # 是否对查询使用索引过滤"parsedQuery": { # 解析查询条件"index_key_name": {"$eq": 1}},"queryHash": "6ACB91B3", # 仅对查询条件进行hash的16进制字符串,帮助识别相同查询条件的 其他查询操作或写操作"planCacheKey": "ACADC259", # 和查询关联的计划缓存的hash键"winningPlan": { # 查询优化器 选择的最优执行计划,此计划包含多个 树状结构的子阶段(一个查询计划需要多个阶段来完成);"stage": "FETCH", # 父阶段;查询方式"inputStage": { # 子阶段"stage": "IXSCAN", # 子阶段的查询方式"keyPattern": { # 索引模式"index_key_name": 1},"indexName": "index_key_name_1", # 索引名称"isMultiKey": false, # 是否是复合索引"multiKeyPaths": { # 复合索引路径"index_key_name": []},"isUnique": true, # 是否是唯一索引"isSparse": false, # 是否是稀疏索引"isPartial": false, # 是否是部分索引"indexVersion": NumberInt("2"), # 索引版本"direction": "forward", # 索引方向"indexBounds": { # 索引查询的范围边界"index_key_name": [ # 创建索引的key"[1.0, 1.0]" # 边界范围]}}},"rejectedPlans": [] # 查询又花钱 拒绝的执行计划},"executionStats": { # 详细的执行统计信息"executionSuccess": true, # 是否执行成功"nReturned": NumberInt("0"), # 符合查询条件的文档个数"executionTimeMillis": NumberInt("0"), # 选择某个查询计划和执行查询 所耗费的总时间(毫秒)"totalKeysExamined": NumberInt("0"), # 扫描的索引总行数"totalDocsExamined": NumberInt("0"), # 扫描的文档总次数(即使同一个文档如果被扫描2次,则此值为2),常见于 stage为 COLLSCAN/FETCH"executionStages": { # 用树状形式 描述 详细的执行计划"stage": "FETCH", # 查询方式"nReturned": NumberInt("0"),"executionTimeMillisEstimate": NumberInt("0"), # 估计执行时间(毫秒)"works": NumberInt("1"), # 指定查询执行阶段执行的“工作单元”的数量。查询执行将其工作划分为小单元。# “工作单元”可能包括检查单个索引键、从集合中获取单个文档、对单个文档应用投影或进行内部簿记"advanced": NumberInt("0"), # 由这一阶段返回到它的父阶段的中间结果或高级结果的数量。"needTime": NumberInt("0"), # 未将中间结果提前到其父阶段的工作循环数"needYield": NumberInt("0"), # 为了让写操作执行,而让出读锁的次数"saveState": NumberInt("0"), # 查询阶段暂停处理并保存其当前执行状态的次数,例如准备放弃其锁"restoreState": NumberInt("0"), # 查询阶段恢复已保存的执行状态的次数,例如,在恢复以前生成的锁之后。"isEOF": NumberInt("1"), # 执行阶段是否已到达最后一个; 1:是 0:不是"docsExamined": NumberInt("0"), # 扫描文档总次数"alreadyHasObj": NumberInt("0"),"inputStage": {"stage": "IXSCAN","nReturned": NumberInt("0"),"executionTimeMillisEstimate": NumberInt("0"),"works": NumberInt("1"),"advanced": NumberInt("0"),"needTime": NumberInt("0"),"needYield": NumberInt("0"),"saveState": NumberInt("0"),"restoreState": NumberInt("0"),"isEOF": NumberInt("1"),"keyPattern": {"index_key_name": 1},"indexName": "index_key_name_1","isMultiKey": false,"multiKeyPaths": {"index_key_name": []},"isUnique": true,"isSparse": false,"isPartial": false,"indexVersion": NumberInt("2"),"direction": "forward","indexBounds": {"index_key_name": ["[1.0, 1.0]"]},"keysExamined": NumberInt("0"), # 通过索引扫描的文档总个数"seeks": NumberInt("1"), # 为了完成索引扫描,必须将索引游标搜索到新位置的次数。"dupsTested": NumberInt("0"),"dupsDropped": NumberInt("0")}},"allPlansExecution": [] # 在计划选择阶段,获胜计划和被拒绝计划的部分执行信息},"serverInfo": { # mongo服务信息"host": "aa8f4be","port": NumberInt("27010"),"version": "4.2.0","gitVersion": "a4b751dcf51dd249c5865812b390cfd"},"ok": 1
}
关键字段解析
字段名称 | 含义 |
---|---|
stage |
COLLSCAN:全表扫描 IXSCAN:索引扫描 FETCH:根据索引去检索指定文档 SHARD_MERGE:将各个分片返回数据进行合并 SHARDING_FILTER: 分片过滤 SORT:表明在内存中进行了排序 LIMIT:使用limit限制返回数 SKIP:使用skip进行跳过 IDHACK:针对_id进行查询 |
nReturned | 实际返回的文档个数 |
totalKeysExamined | 扫描的索引总行数 |
totalDocsExamined | 扫描的文档总行数 |
executionTimeMillis | 执行耗费时间(毫秒) |
使用方法
- stage 查看 对集合的 查询方式,是否全表扫描还是索引扫描等等,来判断好坏;
- 根据 nReturned,totalKeysExamined,totalDocsExamined 3个字段的值 来判断 扫描集合的效率; totalDocsExamined和nReturned 越接近越好,表名 搜索效率越高,如果扫描1万行只返回1行,则表名 效率低下,可以考虑使用索引;
Mongo中执行查询语句过程
从上述 返回的explain结果可以看出,在实际一个查询语句中会生成多个查询计划,并最终筛选出最优的查询计划和 其他被拒绝的查询计划;产生这种结果的原因 在于 mongo 会先通过查询分析器,生成多个查询计划(如,查询一条数据的语句,一个查询计划 使用索引查询,另一个查询计划 使用全表查询),并让其 并行运行所有的查询计划; 然后 查询优化器 会将先返回结果的 查询计划作为真正执行的查询计划,并且 立刻终止其他的查询计划;
mongo的这种 让所有的查询计划 一起执行,谁先返回就选中谁的方式 虽然看起来并发浪费了资源,但是却保证了 每个查询语句的执行计划一定是最优计划;相比较 关系型数据库(如Mysql)的查询优化器(先计算每个查询计划的代价,然后再决定用代价最小的查询计划) 要简单很多;
其他
- 测试时的mongo版本:4.2
- 如果发现 查询条件 没有使用索引,可以 使用 hint()方法强制使用索引;
db.collection.find({age:12}).hint({age:1}) # 查询age=12,且强制使用age索引
相关链接:
cursor.explain() — MongoDB Manualhttps://docs.mongodb.com/manual/reference/method/cursor.explain/#mongodb-method-cursor.explain
https://docs.mongodb.com/v4.2/reference/explain-results/index.htmlhttps://docs.mongodb.com/v4.2/reference/explain-results/index.html
Mongo explain()使用相关推荐
- mongo explain分析详解
1 为什么要执行explain,什么时候执行 explain的目的是将mongo的黑盒操作白盒化. 比如查询很慢的时候想知道原因. 2 explain的三种模式 2.1 queryPlanner 不会 ...
- java mongo hint_聊一聊mongodb中的 explain 和 hint
原标题:聊一聊mongodb中的 explain 和 hint 看到explain和hint的时候,第一个想到的就是mysql,确实,这就是在mysql中借鉴过来的,既然是借鉴过来的,我想大家都知道这 ...
- Ubuntu系统查看mongo得慢日志,及一些操作
摘要 在MySQL中,慢查询日志是经常作为我们优化查询的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是开启Profiling功能.该工具在运行的实例上收集有关MongoDB的写操作 ...
- mongo的php查询,使用PHP进行简单查询的mongo查询速度慢
我有一个非常简单的使用PHP执行的Mongo Query. 我相信查询执行得非常快,因为当我在终端上运行它时,它几乎可以立即完成,并且当我解释()时,它表明它正在1-2ms内执行. 但是,当我去迭代游 ...
- springboot mongo查询固定字段_你真的会用索引么?[Mongo]
一次奇怪的查询经历 如何奇怪了? 对同一张表,用同样的SQL,查询200万条数据耗时100ms,查询二十条数据却耗时30s. 数据量少了10万倍,完全不是一个数量级的数据,耗时却多了300倍. 明明加 ...
- mongo数据库CRUD
#准备 从官网下载合适的安装包.这里以win10为例,一路next即可完成安装.安装完成后,进入这个目录: C:\Program Files\MongoDB\Server\4.0\bin\ 在当前目录 ...
- mongo(四)索引
mongo(四)索引 根据这里http://www.cnblogs.com/huangxincheng/archive/2012/02/29/2372699.html 首先,需要构造一些数据,如下利用 ...
- php mongo 类,mongo php类
/** * mongo 类 * User: wujp * Date: 13-10-12 * Time: 下午5:48 */ class Mongo_DB { #链接 public $conn = nu ...
- 如何通过MongoDB自带的Explain功能提高检索性能?
MongoDB 索引 \\ 每当大家谈到数据库检索性能的时候,首先提及的就是索引,对此,MongoDB 也不例外.就像大家读一本书,或者查字典一样,索引是书的目录,让你方便的能够在上百页的书中找到自己 ...
最新文章
- 资深首席架构师眼中的架构应该是怎样的?【转】
- 基于 Docker 的现代软件供应链
- freemarker写入word【未完,待续】
- BZOJ2216: [Poi2011]Lightning Conductor
- int a[5]={}, a+1与(int*)a+1的区别
- Elasticsearch】 es Match Query
- 在JWT令牌转获取私有化声明时出错,java.util.LinkedHashMap cannot be cast to cn.mar.crm.sys.entity.SysUser
- html5各种页面切换效果和模态对话框
- 【转载】【原创】贵在,难在,成在
- 网易云爬取歌词进行歌词词云可视化
- 一些常见html5语义化标签
- css引入矢量图标_IconFont图标引用的方法步骤(代码) -
- python培训班靠谱吗-python编程培训 python培训靠谱吗
- 新闻资讯android版
- Your branch and ‘origin/master‘ have diverged,
- 企立方:拼多多快速运营法则
- python 常用库收集
- java自动发图文微博_使用node搭建自动发图文微博机器人的方法
- 几何光学学习笔记(13)- 4.2双平面镜成像
- 聚观早报 | 苹果首款头显明年1月亮相;米哈游投资信托「打水漂」