Explain

从之前的文章中,我们可以知道explain()能够提供大量与查询相关的信息。对于速度比较慢的查询来说,这是最重要的诊断工具之一。通过查看一个查询的explain()输出信息,可以知道查询使用了哪个索引,以及是如何使用的。

最常见的explain()的输出有两种类型:使用索引的查询和没有使用索引的查询。

在上一篇MongoDB的博客可以看到两种类型的explain如下:

1. 没有使用索引时

{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1001,
"nscanned" : 1001,
"nscannedObjectsAllPlans" : 1001,
"nscannedAllPlans" : 1001,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 7,
"nChunkSkips" : 0,
"millis" : 1,
"server" : "user:27017",
"filterSet" : false
}

2. 使用索引时

{
"cursor" : "BtreeCursor username_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"username" : [
[
"user1000",
"user1000"
]
]
},
"server" : "user:27017",
"filterSet" : false
}

我们以有索引的结果为例,来依次看一下这些字段代表的意思

  • "cursor" : "BtreeCursor username_1"
    BtreeCursor表示本次查询使用了索引,具体来说,是使用了“username”上的索引{“username”:1}。如果查询要对结果进行逆序遍历,或者使用了多键索引,就可以在这个字段中看到“reverse”和“multi”这样的值。
  • "isMultiKey" : false
    用于说明本次是否使用了多键索引。
  • "n" : 1
    本次查询返回的文档数量
  • "nscannedObjects" : 1
    这是MongoDB按照索引指针去磁盘上查找实际文档的次数。如果查询包含的查询条件不是索引的一部分,或者说要求返回不在索引内的字段,MongoDB就必须依次查找每个索引条目指向的文档。
  • "nscanned" : 1
    如果有使用索引,那么这个数字就是查找过的索引条目数量,如果本次查询是一次全表扫描,那么这个数字就代表检查过的文档数目。
  • "scanAndOrder" : false
    MongoDB是否在内存中对结果集进行了排序
  • "indexOnly" : false
    MongoDB是否只使用索引就能完成此次查询。在本例中,MongoDB只使用索引就找到了全部的匹配文档,从“nscanned”和“n”相等就可以看出来。然而,本次查询要就返回匹配文档中的所有字段,而索引只包含“username”这个字段,如果就本次查询修改为{"_id":0, "username":1},那么本次查询就可以被索引覆盖了,"indexOnly"的值就会是true。
  • "nYields" : 0
    为了让写入请求能够顺利执行,本次查询暂停暂停的次数。如果有写入请求需求处理,查询会周期性的释放他们的锁,以便写入能够顺利执行。然而,在本次查询中,没有写入请求,因此查询没有暂停过。
  • "millis" : 0
    数据库执行本次查询所耗费的毫秒数。这个数字越小,说明效率越高。
  • "indexBounds" : {...}
    这个字段描述了索引的使用情况,给出了索引的遍历范围。由于此次查询是精确匹配,所以所以只要查“user1000”这个值就可以了。

Hint

虽然MongoDB查询优化器一般工作的很不错,但是也可以使用hint()来强迫MongoDB使用一个特定的索引。在这种方法下某些情形下会提升性能。一个有索引的collection并且执行一个多字段的查询。传入一个制定的索引,强迫查询使用该索引。

db.users.find({"username":"user1000", "age":30}).hint({"username":1})

注意:请确定你已经创建了相应的索引。

假设在users上有个{"a": 1, "b": 1}的索引,名称是"a_1_b_1",则如下两种方式等价:

db.users.find({"a": 4, "b": 5, "c": 6}).hint({"a": 1, "b": 1})
db.users.find({"a": 4, "b": 5, "c": 6}).hint("a_1_b_1")

也可以强迫查询不适用索引,做表扫描:

db.users.find().hint({"$natural":1})

MongoDB的学习--explain()和hint()的更多相关文章

  1. mongodb之使用explain和hint性能分析和优化

    当你第一眼看到explain和hint的时候,第一个反应就是mysql中所谓的这两个关键词,确实可以看出,这个就是在mysql中借鉴过来的,既然是借鉴 过来的,我想大家都知道这两个关键字的用处,话不多 ...

  2. MongoDB中的explain和hint提的使用

    一.简介 这里简单介绍一下各个工具的使用场景,一般用mysql,redis,mongodb做存储层,hadoop,spark做大数据分析. mysql适合结构化数据,类似excel表格一样定义严格的数 ...

  3. MongoDB的学习--索引类型和属性(转)

    原文链接:MongoDB的学习--索引类型和属性 索引类型 MongDB的索引分为以下几种类型:单键索引.复合索引.多键索引.地理空间索引.全文本索引和哈希索引 单键索引(Single Field I ...

  4. NoSQL之【MongoDB】学习(三):配置文件说明

    摘要: 继上一篇NoSQL之[MongoDB]学习(一):安装说明 之后,知道了如何安装和启动MongoDB,现在对启动时指定的配置文件(mongodb.conf)进行说明,详情请见官方. 启动Mon ...

  5. [转载]MongoDB开发学习(2)索引的基本操作

    索引能够极大的提高查询的效率.在数据库中简历索引必不可少. 在MongoDB中可以很轻松的创建索引. 默认索引_id_ 开启MongoDB服务器,创建数据库cnblogs,创建集合Users .(关于 ...

  6. 双刃剑MongoDB的学习和避坑

    双刃剑MongoDB的学习和避坑 MongoDB 是一把双刃剑,它对数据结构的要求并不高.数据通过key-value的形式存储,而value的值可以是字符串,也可以是文档.所以我们在使用的过程中非常方 ...

  7. mongodb数据库学习【安装及简单增删改查】

    //@desn:mongodb数据库学习 //@desn:码字不宜,转载请注明出处 //@author:张慧源  <turing_zhy@163.com> //@date:2018/08/ ...

  8. Mongodb索引和执行计划 hint 慢查询

    查询索引 索引存放在system.indexes集合中 > show tables address data person system.indexes 默认会为所有的ID建上索引 而且无法删除 ...

  9. Mongodb数据库学习系列————(一)Mongodb数据库主从复制的搭建

    Mongodb数据库主从复制的搭建 Writeby:lipeng                                    date:2014-10-22 最近项目上用到了位置查询,在网上 ...

随机推荐

  1. oracle日常——sqlplus客户端登录

    1.进入cmd 2.命令--sqlplus--提示输入帐号与密码 3.进入后,就可以直接键入sql命令 ps.sql命令后面需要添加分号后才可以回车执行

  2. 在VS中操作Mysql数据库

    1.实现mysql数据库与VS的连接,需要安装两个插件,作者装的是mysql-connector-net-6.9.9.msi和 mysql-for-visualstudio-1.2.6.msi. 2. ...

  3. 【iOS】Quartz2D绘图路径Path

    一.绘图路径 A.简单说明 在画线的时候,方法的内部默认创建一个path.它把路径都放到了path里面去. 1.创建路径  cgmutablepathref 调用该方法相当于创建了一个路径,这个路径用 ...

  4. SAP MM移动平均价和标准价逻辑

    从收货到领用,S一直都是以标准价格计算,V是实时更新 S 时将差异结转到在产品,产品中,最后结转到生产成本,最终到利润.具有计划性,可以控制考核 V 是实时更新,出现差异直接对应材料中调整.价格可以直 ...

  5. 如何判断单选按钮radio被选中

    今天要写一个单选按钮选中之后显示某些内容,首要问题就是当选中如何获取到值! html代码如下 <input class="joined" type="radio&q ...

  6. StringBuilder 用法和div获取

    StringBuilder strHtml = new StringBuilder(); strHtml.Append("<tr>"); strHtml.Append( ...

  7. JS encode decode

    网上查到的全都是escape,和需要的编码不是一回事,好不容易找到的结果 保存下来以备以后使用 js对文字进行编码涉及3个函数:escape,encodeURI,encodeURIComponent, ...

  8. Hadoop学习历程(三、第一个程序)

    根据之前的操作,我们已经可以正常的启动Hadoop了,关于真正的集群我会在之后进行说明.现在我们来看一下第一个程序吧 1. 在eclipse上建立一个java项目 2. 将 /usr/hadoop/s ...

  9. shuffle的工作原理

    Shuffle的正常意思是洗牌或弄乱,可能大家更熟悉的是Java API里的Collections.shuffle(List)方法,它会随机地打乱参数list里的元素顺序.如果你不知道MapReduc ...

  10. 面向对象多继承(c3算法)、网络基础和编写网络相关的程序

    一.面向对象多继承(c3算法) a.有多个父类先找左,再找右,如下示例: class A(object): pass class B(object): def f1(self): print('B') ...