Index 能够提高查询的性能,如果没有Index,MongoDB必须扫描整个collection,从collection的第一个doc开始,直到最后一个doc,即使第一个doc之后的所有doc都不满足查询条件。如果在Collection上有合适的Index,例如,unique index,那么MongoDB在按照index key查找到一个doc之后,就不会继续对其他doc查询,极大地提高查询性能。

MongoDB的 Index 结构跟关系型DB的NonClustered Index相似,都是BTree结构,在每个leaf node中,除了index key之外,还存储相应doc在disk上的地址。在MongoDB中,没有clustered index,因此,Collection初始的物理存储跟doc插入的顺序有关,MongoDB按照doc插入的顺序,依次将doc存储在disk上,插入顺序上相邻的doc在disk的物理位置上也是相邻的;对doc的修改可能对 collection 的物理存储发生变化,如果doc的修改不会导致doc的size增加,那么doc会继续存储在原来的存储空间中,而不会对collection的物理存储有影响,一旦修改操作导致doc的size增加,导致doc发生移动,那么collection的物理存储就会发生变化。

一,doc的移动影响collection的物理存储

如果数据修改增加了doc的size,使其不能继续存放在原来的存储空间中,那么MongoDB必须将其移动到collection的末尾,原先的存储空间被闲置,导致doc的存储密度下降,会严重影响查询性能。doc的移动过程是非常慢的,相当于在一个原子操作中,先做doc的 delete 操作,后做doc的 insert 操作。

doc移动的过程如下图所示:

对doc B进行修改,使其Size增大,原先的位置不能容纳B,MongoDB将B移动在Collection的末尾。原来的存储空间被闲置。

二,创建index

MongoDB的index是BTree 结构,BTee结构的特点是:查询每个值所要进行查询的次数时固定的,最小的值存储在最左边的叶子节点上,做大的值存储在最右边的叶子节点上,如图:

MongoDB默认按照“_id”字段的升序创建index,最后创建的doc位于index的右侧。如果每次查询时,都是查询最后的N个doc,那么按照"_id"的值倒叙查询,limit 前100,查询性能是十分快速的。也可以手动创建符合业务需要的Index,MongoDB使用 db.collection.createIndex(keys,option)函数创建index。

keys的格式是:{field:1/-1,,},field是doc的字段,1/-1 表示按照field排序的方向创建index:1表示按照field的升序创建,-1表示按照field的降序创建。

db.collection.createIndex(keys,option) 

1,创建示例数据,按照 age 字段升序创建index

创建的Index按照age的升序存储age字段,在叶子节点中,除了age字段,叶子节点还会存储doc的地址(指针),用于定位相应的doc,查询除index key(age)之外的其他字段。下面的语句创建的index name是 age_1。

for(i=0;i<10000;i++)
{db.foo.insert({"idx":i,name:"user "+1,age:i%90})
}--create index by age ascendant
db.foo.createIndex({age:1})

2,查看查询的query plan

在示例中,由于查询语句中没有设置projection,MongoDB返回doc中的所有fields,由于index:age_1只包含age字段,其他字段必须定位到原doc中获取,因此多一次寻址操作。

db.foo.find({age:22}).explain("executionStats")

在查询语句中设置Projection,只返回age字段,那么index:age_1 就能包含结果集中所有字段,不需要定位到原doc中,不仅提高查询性能,而且减少Disk IO 和内存的使用量,因此,应对每个结果集设置Projection,不要返回"_id"字段等其他不需要的字段。通过搜索index就能获取所有field的index是覆盖索引(convered index),覆盖索引不需要定位到原doc中。

db.foo.find({age:22},{age:1,_id:0}).explain("executionStats")

三,index 和 排序

排序是一个非常耗费内存资源的操作,在MongoDB中,如果排序的中间结果集大小消耗的系统内存超过32MB,MongoDB就会报错,拒绝如此多的数据进行排序。32MB是一个阈值,如果超出值,那么必须使用 index 来获取经过排序的数据集。

MongoDB:When unable to obtain the sort order from an index, MongoDB will sort the results in memory, which requires that the result set being sorted is less than 32 megabytes. When the sort operation consumes more than 32 megabytes, MongoDB returns an error.

通过Index来执行排序操作,要求排序的字段和index key的前缀字段相同,如果满足该条件,那么MongoDB会直接返回顺序的结果集,而不需要执行实际的排序操作。例如,如果index key是{age:1,name:1},如果排序操作是sort({age:1}),或 sort({age:1,name:1}),符合index前缀排序,那么结果集会直接返回,不需要排序;如果排序操作是sort({name:1}),或sort({name:1,age:1}),不符合index前缀排序,结果集还是需要在内存中进行排序,如果内存消耗超过32MB,MongoDB报错。

示例,符合前缀排序的Index 和 sort 操作

 db.foo.find({age:22}).sort({age:1})

由于MongoDB通过Index来执行排序操作,并且MongoDB对排序操作消耗的内存资源有严格限制,因此,在创建index,应在查找和排序之间做折衷,在满足排序操作的前提下,使查询性能更高。在创建index时,使用 {"Sort Key":1, "query filter":1} 格式是非常有用。

四,对内嵌doc进行索引

MongoDB index的强大之处在于能够在内嵌doc的字段上创建index,创建的语法和普通doc一致,在引用内嵌doc中的字段时,使用dot notation,可以对任意深度的内嵌doc字段建立index。

例如,doc结构如下,contact是内嵌doc,按照 contact.phone 字段升序创建索引。

{
name:"u1",
age:22,
contact:{phone:123email:"xx@163.com"}
}--create index
db.foo.createIndex({"contact.phone":1})

五,Index 维护

1,查看在collection上创建的index

使用db.collectionName.getIndexes() 查看给定collection上的所有index信息:

  • key是指index key的定义,包括两部分:key 和排序的方向;
  • name是index name;
  • ns是namespace;
  • v 标识index 版本,如果索引中包含"v":1,说明index是以新格式存储的,性能较高。
db.collection.getIndexes()

2,删除index

db.collection.dropIndex(index)

方式一,按照index name 删除index

db.foo.dropIndex("age_1")

方式二,按照Index key删除index

db.foo.dropIndex({age:1})

3,重建collection中的所有index

db.collection.reIndex()

The db.collection.reIndex() drops all indexes on a collection and recreates them. This operation may be expensive for collections that have a large amount of data and/or a large number of indexes.

参考doc:

MongoDB CRUD Concepts

cursor.explain()

Indexes

MongoDB 使用Index相关推荐

  1. mongodb AND查询遇到多个index时候可能会做交集——和复合索引不同

    关于MongoDB中索引文档的一个问题? - To illustrate index intersection, consider a collection orders that has the f ...

  2. NoSQL 之 Morphia 操作 MongoDB

    上两篇文章:http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html http://www.cnblogs.com/hoojo/arch ...

  3. mongodb java 学习_《 mongodb 学习 》java 基本操作

    环境 springboot 结合 monggodb 一.pom.xml org.springframework.boot spring-boot-starter-data-mongodb 配置: sp ...

  4. MongoDB与Spring Data项目

    如今,我们所有人都在观察NoSql解决方案的爆炸式增长. 我已经习惯了RDBMS,但这些并不是您可能遇到的所有挑战的解决方案. 根据最近的经验,我有机会使用MongoDB –文档数据库. 在本文中,我 ...

  5. mongodb lbs java_LBS JAVA Spring mongoDB

    基本介绍 位置服务(LBS)解决的主要问题是当前位置周围某个范围内的人或场所. 在传统的解决方案,开发人员需要根据复杂的几何运算与大量的SQL语句进行查找,这无疑加大的开发人员的开发难度. 现在我们需 ...

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

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

  7. mongodb教程_MongoDB教程

    mongodb教程 Welcome to the MongoDB tutorial index post. MongoDB is one of the most widely used NoSQL d ...

  8. MongoDB 索引(一)

    索引支持在MongoDB中高效执行查询.如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,以选择那些匹配查询语句的文档.如果查询存在适当的索引,MongoDB可以使用该索引来限制它 ...

  9. MongoDB一篇从入门到实战

    目录 MongoDB 数据库介绍 01.MongoDB简介 1.性能高 2.支持分布式 3.安装和部署容易 4.便于开发 5.NOSQL与SQL对比 02.文档存储结构 1.键值对 2.文档 3.集合 ...

  10. Spring data mongodb实现LBS

    基本介绍 位置服务(LBS)解决的主要问题是当前位置周围某个范围内的人或场所. 在传统的解决方案,开发人员需要根据复杂的几何运算与大量的SQL语句进行查找,这无疑加大的开发人员的开发难度. 现在我们需 ...

最新文章

  1. 面试官问你想找什么工作_找工作时如何面试面试官
  2. 杭电1175简单搜索 连连看
  3. python 项目构建工具_python的构建工具setup.py
  4. 工作经验(体感开发篇)
  5. K-Median Subsequence
  6. 圆桌的项目Alpha冲刺——测试
  7. js reduce实现中间件_Laravel中间件实现原理及实例分析
  8. 前端学习(664):逻辑中断逻辑或
  9. 【机器学习】opencv-人脸识别
  10. JAVA调用接口简单封装,Mvp+Retrofit2+RxJava2 项目中使用的简洁封装
  11. Uva1343-The Rotation Game-IDA*算法
  12. 2021年北京高考成绩排名查询,2021年北京高考各高中成绩及本科升学率数据排名及分析...
  13. 【私有,不喜勿入】健康
  14. Golang线程池gpool
  15. 7 125 kHz RFID技术
  16. python拼音怎么写-Python汉字转换成拼音
  17. 用Python如何开发Excel宏脚本?新手必学
  18. JZOJ ???? Or
  19. 电影《蓝色大门》有感
  20. android:sharedUserId=android.uid.system 的使用

热门文章

  1. 头孢一代比一代强吗?
  2. 集线器、交换机、路由器
  3. 第8章 卷积神经网络
  4. java生成pdf旋转_Java 设置PDF页面大小/旋转、纸张方向、页边距
  5. Android Wi-Fi源码分析之wpa_supplicant初始化(三):wpa_supplicant_add_iface函数分析
  6. Centos删除文件空间不释放怎么办
  7. 密歇根州立大学教授刘小明讲解:人脸识别的新技术 | 大牛讲堂
  8. Excel 生成均匀分布、正态分布随机数
  9. 第八届蓝桥杯国赛 Java B组 第五题 标题:填字母游戏
  10. android立方体旋转动画,如何画出一个旋转的立方体