文档章节

mongoDB 3.0+ explain

learn_more
 learn_more
发布于 2018/02/07 17:22
字数 1334
阅读 167
收藏 2

 

1、explain 函数

3.0 前后版本的explain差别很大,因为版本既然已经升级就没必要去研究低版本的了。

explain 我们叫做查询优化器,mongo 与其他数据库比如MySQL还是有所不同,所谓不同不是结果不同,而是过程不同。那么mongo的优化器确定最优查询线路的过程是怎么样的呢?

1)如果一个索引能够精确匹配一个查询,那么就确定使用这个索引,同时缓存起来,下次直接使用

2)如果有多个索引,那么mongo 分别并行使用这些索引去检索数据,最早返回 100 个结果的就是最优的,同时缓存起来,下次直接使用

3)如果有重建索引、结果集发生变化、已经执行过1000次的查询的任何一种情况,mongo都会清空之前的缓存,重新使用 1 、2 来确定新的最优索引。

 

看着这个过程,肯定和MySQL的不一致,MySQL是每次都对SQL进行分析查找最优索引,而且他不是真正的去获取数据。

 

 

2、语法

1)db.getCollection('examClassStat').find({schoolId:145}).explain(str);

str = null 或 无参,只会把最基础的 queryPlanner 显示出来,当然有附带的 serverInfo 信息

str = queryPlanner,和第一种情况完全一致

str = executionStats,除了 queryPlanner 信息,还有 executionStats 详细信息

str = allPlansExecution,会显示 queryPlanner 、executionStats、allPlansExecution 三部分

 

 

3、注意事项

1)一般情况下直接使用无参的 explain 就 OK 了,因为简单看一下是否使用索引就OK,真正说发现很慢的时候才会一步步深入的去获取信息。

 

2)主要是 explain 返回的两个对象要分清轻重,其一就是 winningPlan.stage 这个表示最后一阶段执行的类型;其二就是 winningPlan.inputStage.stage 表示第一阶段执行的类型;那么可以这样任务先执行的信息都放在 inputStage 里,最后执行的放在 winningPlan 里。

第一阶段就是真正使用索引地方,因此 winningPlan.inputStage.stage 是关键

第二阶段是指获取文档的地方,即 winningPlan.stage , 这个状态其实意义没那么重要了。

 

3)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 应该是 IXSCAN 等用到索引的类型。

 

4)除了 stage 外,还有几个你常用的字段

-- 数量上,最优的结果自然是 三者都相等了,而且值小的话就再好不过了

executionStats.nReturned:实际返回总数

executionStats.totalKeysExamined:第一阶段遍历的总数

executionStats.totalDocsExamined:第二阶段遍历的总数

 

-- 时间上,值越小说明越快

executionStats.executionTimeMillis:实际耗费总时间

executionStats.executionStages.executionTimeMillisEstimate:第二阶段耗费时长

executionStats.executionStages.inputStage.executionTimeMillisEstimate:第一阶段耗费时长

 

5)通过 explain 分两个阶段获取数据可以得知,如果数据量很少的情况下,那么还是用索引去检索数据的话反而会适得其反,因为使用索引需要先查找索引条目,然后通过索引条目找到对应的文档;但是如果你是全表扫描的话,只需要第二个阶段就能完成。

这个也只是一个特例,不管怎么样,互联网时代数据量总会变大。

另外,想要确定使用哪个索引是可以使用 hint 函数, find().hint("index_name");

 

4、字段说明

db.getCollection('examClassStat')

.find({schoolId:145},{examBaseId:1,"_id":0}).explain("allPlansExecution")

------输出如下

{
    "queryPlanner": {
        "plannerVersion": 1,
        "namespace": "develop.examClassStat",
        "indexFilterSet": false,
        "parsedQuery": { /*  解析查询语句  */
            "schoolId": {
                "$eq": 145
            }
        },
        "winningPlan": {
            "stage": "PROJECTION",   /*  最后一阶段的执行类型  */
            "transformBy": {
                "examBaseId": 1,
                "_id": 0
            },
            "inputStage": {
                "stage": "COLLSCAN",  /*  第一阶段的执行类型  */
                "filter": {
                    "schoolId": {
                        "$eq": 145
                    }
                },
                "direction": "forward" /*  与索引无关,查询方向,backward 则相反  */
            }
        },
        "rejectedPlans": []   /*  非最优而被查询优化器reject的  */
    },
    "executionStats": {
        "executionSuccess": true,
        "nReturned": 0,  /*  返回结果总数  */
        "executionTimeMillis": 0, /*  执行总耗时,毫秒 */
        "totalKeysExamined": 0, /*  通过索引命中的总数,或是索引扫描的总数  */
        "totalDocsExamined": 849, /*  文档扫描总数  */
        "executionStages": { /*  最后一阶段执行的详细信息  */
            "stage": "PROJECTION",   /*  最后一阶段的执行类型   */
            "nReturned": 0,
            "executionTimeMillisEstimate": 0,   /*  totalDocsExamined 的耗时   */
            "works": 851,
            "advanced": 0,
            "needTime": 850,
            "needYield": 0,
            "saveState": 6,
            "restoreState": 6,
            "isEOF": 1,
            "invalidates": 0,
            "transformBy": {
                "examBaseId": 1,
                "_id": 0
            },
            "inputStage": {   /* 第一阶段执行的详细信息  */
                "stage": "COLLSCAN", /*  执行该阶段所用的类型,COLLSCAN 全表扫描  */
                "filter": {
                    "schoolId": {
                        "$eq": 145
                    }
                },
                "nReturned": 0,
                "executionTimeMillisEstimate": 0, /*  totalKeysExamined 的耗时   */
                "works": 851,
                "advanced": 0,
                "needTime": 850,
                "needYield": 0,
                "saveState": 6,
                "restoreState": 6,
                "isEOF": 1,
                "invalidates": 0,
                "direction": "forward",
                "docsExamined": 849
            }
        },
        "allPlansExecution": []   /* 所有索引在并行执行的详细结果  */
    },
    "serverInfo": {
        "version": "3.4.7",
        "gitVersion": "cf38c1b8a0a8dca4a11737581beafef4fe120bcd"
    },
    "ok": 1
}

 

© 著作权归作者所有

learn_more
粉丝 93
博文 240
码字总数 210196
作品 0
深圳
程序员
私信 提问
加载中

评论(0)

MongoDB 3.0新特性概述

MongoDB 在 2015年3月3日 跳过了 MongoDB 2.8版本,直接在 MongoDB 2.6版本后,发布了MongoDB 3.0版本。 随后在 2015年3月17日 发布了 MongoDB 3.0.1 版本; 在 2015年4月9日发布了 MongoDB ...

xinsir999
2018/05/02
0
0
MongoDB 3.0安装并随win7,win10开机自启

MongoDB的官方下载站是http://www.mongodb.org/downloads,可以去上面下载最新的程序下来。在下载页面可以看到,对操作系统支持很全面,OS X、Linux、Windows、Solaris都支持,而且都有各自的...

mosaic101
2015/08/08
455
0
Linux中安装MongoDB(2015-11-03 00:51:24)

背景:之前有过一次试过安装MongoDB,但是网上说的方法各种各样,再加上虚拟机有问题,所以就导致没安装成功,今天在群里面提问,经过一哥们的提醒,告诉我直接上官网,按照官网上的安装方法...

Dreyer
2015/11/03
130
0
Mongodb学习(安装篇): 在centos下的安装

下载解压文件 解压文件 查看解压文件 将/lamp/mongodb-linux-i686-2.2.2/bin目录拷贝到/usr/local/mongodb下 创建数据存放和日志文件: 启动进程(以后台Daemon形式运行服务) 查看mongod进程 ...

tw5566
2013/01/19
115
0
php扩展mongo和mongodb对应的MONGODB版本

PHP Driver MongoDB 2.4 MongoDB 2.6 MongoDB 3.0 MongoDB 3.2 MongoDB 3.4 PHPLIB 1.1 + mongodb-1.2 ✓ ✓ ✓ ✓ ✓ PHPLIB 1.0 + mongodb-1.1 ✓ ✓ ✓ ✓ mongodb-1.1 ✓ ✓ ✓ ✓ mong......

gaolongquan
2017/11/01
372
0

没有更多内容

加载失败,请刷新页面

加载更多

21天完美搞定Vue框架技术(第3天)

前言: 上一节我们主要学的是【选项合并】,了解了初始化阶段各个选项的合并策略, 本节课我们来学一下【数据代理】这个知识点。 1、数据代理的定义 数据代理,也叫作数据劫持。有两个核心作...

有鱼是只猫
27分钟前
31
0
OSChina 周二乱弹 —— 一山里不容二猫

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《数え歌》- 池田綾子 手机党少年们想听歌,请使劲儿戳(这里) @诺墨 :哈哈哈哈...

小小编辑
41分钟前
43
1
敏捷开发验收评审会议

迭代验收评审是Scrum中的重要活动之一,迭代验收评审会议召开过程是否符合敏捷原则,实践是否贴近实际,参照以下:要点一:参加迭代验收评审会议的角色是否完整和投入 ●敏捷团队所有...

沐沐爸比
今天
43
0
js 获取文件本地内存路径

URL.createObjectURL(file)

DrChenXX
今天
51
0
CentOS 6.5 安装 Hadoop 集群【未完】

1、安装 CentOS 6.5 2、关闭 iptables 3、关闭 suliunx 4、修改 IP 4、修改 hostname 5、修改 hosts 6、SSH 免密 7、JDK(1.8)安装 华为镜像直达 8、...

产品哥
今天
59
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部