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()使用相关推荐

  1. mongo explain分析详解

    1 为什么要执行explain,什么时候执行 explain的目的是将mongo的黑盒操作白盒化. 比如查询很慢的时候想知道原因. 2 explain的三种模式 2.1 queryPlanner 不会 ...

  2. java mongo hint_聊一聊mongodb中的 explain 和 hint

    原标题:聊一聊mongodb中的 explain 和 hint 看到explain和hint的时候,第一个想到的就是mysql,确实,这就是在mysql中借鉴过来的,既然是借鉴过来的,我想大家都知道这 ...

  3. Ubuntu系统查看mongo得慢日志,及一些操作

    摘要 在MySQL中,慢查询日志是经常作为我们优化查询的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是开启Profiling功能.该工具在运行的实例上收集有关MongoDB的写操作 ...

  4. mongo的php查询,使用PHP进行简单查询的mongo查询速度慢

    我有一个非常简单的使用PHP执行的Mongo Query. 我相信查询执行得非常快,因为当我在终端上运行它时,它几乎可以立即完成,并且当我解释()时,它表明它正在1-2ms内执行. 但是,当我去迭代游 ...

  5. springboot mongo查询固定字段_你真的会用索引么?[Mongo]

    一次奇怪的查询经历 如何奇怪了? 对同一张表,用同样的SQL,查询200万条数据耗时100ms,查询二十条数据却耗时30s. 数据量少了10万倍,完全不是一个数量级的数据,耗时却多了300倍. 明明加 ...

  6. mongo数据库CRUD

    #准备 从官网下载合适的安装包.这里以win10为例,一路next即可完成安装.安装完成后,进入这个目录: C:\Program Files\MongoDB\Server\4.0\bin\ 在当前目录 ...

  7. mongo(四)索引

    mongo(四)索引 根据这里http://www.cnblogs.com/huangxincheng/archive/2012/02/29/2372699.html 首先,需要构造一些数据,如下利用 ...

  8. php mongo 类,mongo php类

    /** * mongo 类 * User: wujp * Date: 13-10-12 * Time: 下午5:48 */ class Mongo_DB { #链接 public $conn = nu ...

  9. 如何通过MongoDB自带的Explain功能提高检索性能?

    MongoDB 索引 \\ 每当大家谈到数据库检索性能的时候,首先提及的就是索引,对此,MongoDB 也不例外.就像大家读一本书,或者查字典一样,索引是书的目录,让你方便的能够在上百页的书中找到自己 ...

最新文章

  1. 资深首席架构师眼中的架构应该是怎样的?【转】
  2. 基于 Docker 的现代软件供应链
  3. freemarker写入word【未完,待续】
  4. BZOJ2216: [Poi2011]Lightning Conductor
  5. int a[5]={}, a+1与(int*)a+1的区别
  6. Elasticsearch】 es Match Query
  7. 在JWT令牌转获取私有化声明时出错,java.util.LinkedHashMap cannot be cast to cn.mar.crm.sys.entity.SysUser
  8. html5各种页面切换效果和模态对话框
  9. 【转载】【原创】贵在,难在,成在
  10. 网易云爬取歌词进行歌词词云可视化
  11. 一些常见html5语义化标签
  12. css引入矢量图标_IconFont图标引用的方法步骤(代码) -
  13. python培训班靠谱吗-python编程培训 python培训靠谱吗
  14. 新闻资讯android版
  15. Your branch and ‘origin/master‘ have diverged,
  16. 企立方:拼多多快速运营法则
  17. python 常用库收集
  18. java自动发图文微博_使用node搭建自动发图文微博机器人的方法
  19. 几何光学学习笔记(13)- 4.2双平面镜成像
  20. 聚观早报 | 苹果首款头显明年1月亮相;米哈游投资信托「打水漂」

热门文章

  1. leetcode 动态规划 514. 自由之路
  2. 玩客云刷armbian安装php环境_玩客云刷机为armbian后,挂载SD卡到www目录的脚本
  3. iOS 防止抓包(SSL Pinning)
  4. 开发板(Linux)挂载SD卡
  5. 程序员平时上哪些网站
  6. 基于LabVIEW带音乐流水灯万年历的智能计算器
  7. 读李鼎祚之《周易集解》
  8. ubuntu 擦除磁盘_如何在Linux中格式化(擦除)DVD + RW / DVD-RW磁盘
  9. css3实现六边形照片展示
  10. php中文网线上班怎么样,数组--PHP中文网第九期线上班