女主宣言

在优化MongoDB性能时,理解和使用索引是非常重要的。本次小编就给大家整理了MongoDB索引的相关文章,来帮助大家提升对MongoDB索引的理解。

PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!

索引是一个拥有自己唯一存储的对象,它为集合提供了一条快速访问路径。索引的存在主要是为了提高性能,因此,在优化MongoDB性能时,有效理解和使用索引是非常重要的。

1

B-树索引

B-树索引是MongoDB的默认索引结构。以下是B-树索引结构高等级的概述。

B-树索引具有分层树结构。树顶部是头部块。此块包含指向任何给定范围的键值的适当分支块的指针。分支块通常会指向适当的叶子块以获得更具体的范围,或者对于更大的索引,则指向另一个分支块。 叶子块包含一个键值列表和指向磁盘上文档位置的指针。

查看上面的图,让我们想象一下MongoDB如何遍历这个索引。 如果我们需要访问“BAKER”的记录,我们首先会查阅头部块。 头部块会告诉我们,从A到K开始的键值存储在最左边的分支块中。 访问这个分支块,我们发现从A到D开始的键值存储在最左边的叶子块中。 咨询这个叶子块,我们发现值“BAKER”以及它关联的磁盘位置,我们将用它来获得有关的文件。

叶子块包含前一个和后一个叶子块的链接。 这允许我们以升序或降序扫描索引,并且允许使用$gt或$lt操作符的范围查询使用索引进行处理。

与其他索引策略相比,B-树索引具有以下优点:

  1. 由于每个叶子节点处于相同的深度,所以性能是非常可预测的。 从理论上讲,集合中的任何文档都不会超过三或四次I/O。

  2. B树为大型集合提供了良好的性能,因为深度最多为四个(一个头部块,两个分支块级别和一个叶子块级别)。 一般来说,没有任何文件需要四个以上的I/O来定位。 实际上,因为头部块几乎总是已经加载到内存中,而分支块通常加载到内存中,所以实际的物理磁盘读取次数通常只有一次或两次。

  3. 因为与前一个和后一个叶子块的链接,所以B-树索引支持范围查询以及精确的查找是可行的。

B-树索引提供了灵活高效的查询性能。但是,在更改数据时维护B-树可能很昂贵。例如,考虑在上面的图表中插入一个键值为“NIVEN”的文档。要插入集合,我们必须在“L-O”块中添加一个新条目。如果在这个区域内有空闲空间,那么成本是很大的,但也许不会过多。但是如果块中没有可用空间会发生什么?

如果叶子块中没有空闲空间用于新条目,则需要索引拆分。必须分配新块,并将现有块中的一半条目移入新块。除此之外,还需要在分支块中添加一个新条目(以便指向新创建的叶子块)。如果分支块中没有空闲空间,则分支块也必须分割。

这些索引拆分是一项昂贵的操作:必须分配新块,并将索引条目从一个块移到另一个块。

2

索引选择性

属性或属性组的选择性是对这些属性的索引的有用性的常用度量。如果文档或索引具有大量的唯一值或重复值很少,则它们是有选择的。例如,DATE_AND_TIME_OF_BIRTH属性将非常有选择性,而GENDER属性将不会被选择。

选择性索引比非选择性索引更有效,因为它们更直接地指向特定的值。MongoDB优化器通常会使用最有选择性的索引。

3

唯一索引

唯一的索引是阻止组成索引的属性的任何重复值的索引。如果你尝试在包含此类重复值的集合上创建唯一索引,则会收到错误消息。同样,如果尝试插入包含重复唯一索引键值的文档,也会收到错误。

通常会创建一个唯一索引,以防止重复值而不是提高性能。 但是,唯一的索引文件通常非常有效 - 它们只能指向一个文件,因此非常有选择性。

4

连接索引

连接索引只是一个包含多个属性的索引。连接键的优点在于它比单个键索引更具有选择性。属性的组合将指向比由单个属性组成的索引更少数量的文档。包含find()或$match子句中引用的所有属性的连接索引将特别有效。

如果你经常查询集合中的多个文档,那么为这些文档创建一个连接索引是一个很好的主意。例如,我们可以通过Surname(姓氏)和Firstname(名字)查询people集合。在这种情况下,我们可能希望在Surname和Firstname上创建一个索引。例如:

db.people.createIndex({ "Surname":1 ,"Firstname":1}  );

使用这样的索引,我们可以快速找到people中所有匹配给定的Surname \ Firstname 组合。 这样的索引比单独的Surname索引或单独的Surname和Firstname索引要有效得多。

如果连接索引只能在所有键出现find()或$match时使用,则连接索引的使用可能会非常有限。幸运的是,连接索引可以非常有效地使用,提供任何初始或主要属性。主要属性是在索引定义中最早指定的属性。

上图显示了将属性添加到连接索引时获得的改进。涉及的查询是在一个1,000,000个文档的people集合上:

db.people.find({    Firstname: "KAREN",Surname: "SMITH",dob: ISODate("2006-01-21T05:55:32.520Z")},{ _id: 0, tel: 1 }
);

例如,我们通过提供Surname,Firstname和dob来检索电话号码。

全面集合扫描要求我们访问所有1,000,000个文档。仅索引surname就减少到20,028个文件 - 实际上是收集中的所有“SMITHS”。添加firstname将文档数减少到188个。通过添加dob,我们只需可以访问两个:访问一个索引条目并从那里访问集合以获取电话号码。 最后的优化是添加电话号码tel属性。 现在我们根本不需要访问集合 - 我们需要的就是索引。 这有时被称为“覆盖”指数。

请注意,覆盖索引通常要求查询包含一个投影,以消除索引中包含的属性以外的所有属性。

5

连接索引指南

以下指南将有助于确定何时使用连接索引,以及如何确定应包含哪些属性以及按何种顺序。

  1. 在集合中为find()或$match条件一起出现的属性创建连接索引。

  2. 如果属性有时会以find()或$match的形式出现,请将它们放在索引的开头。

  3. 如果连接的索引还支持不是所有属性都被指定的查询,则连接索引更有用。 例如,createIndex({"Surname" : 1, "Firstname" : 1})比createIndex({"Firstname" : 1, "Surname" : 1})更有用,因为只针对surname的查询比仅针对firstname的查询更有可能发生。

  4. 属性越有选择性,在索引的前端越有用。但是,请注意,WiredTiger索引压缩可以从根本上缩小索引。当领先的列较少选择时,索引压缩更有效。所以如果属性的顺序不是由前面三个考虑因素决定的,你可能不得不尝试索引顺序。

总结

在MongoDB的优化过程中,只有深入理解内部的索引机制,我们才能更好的提升MongoDB的性能。

扫描下方二维码了解更多内容

有效的MongoDB索引相关推荐

  1. 关于Mongodb索引创建的一些体会

    2019独角兽企业重金招聘Python工程师标准>>> mongodb索引分类以及创建我就不多说了,如果想了解可以直接在百度上搜索,这里我说一下关于索引创建的个人想法. 1.优先给一 ...

  2. MongoDB 索引

    2019独角兽企业重金招聘Python工程师标准>>> 索引Indexes 索引常常用来大幅度的提升查询的性能. 考虑应用程序的查询种类是非常重要的事情,因此你就要定义相关的索引. ...

  3. MongoDB · 引擎特性 · MongoDB索引原理

    MongoDB · 引擎特性 · MongoDB索引原理 数据库内核月报 原文链接 http://mysql.taobao.org/monthly/2018/09/06/ 为什么需要索引? 当你抱怨M ...

  4. MongoDB索引实战技巧

    为什么80%的码农都做不了架构师?>>>    本文内容源自Kyle Banker 的 MongoDB In Action一书.主要描述了MongoDB索引相关的一些基础知识和使用技 ...

  5. mongodb 索引建立问题

    mongodb  索引建立问题 1.主从库索引建立不是同步建立: MONGODB 2.6.6 版本,索引建立并不是同步的,而是主库建立完成后,从库接着建立索引.     不知是3.0版本是否也一样,以 ...

  6. MongoDB 索引-9

    MongoDB 索引 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录. 这种扫描全集合的查询效率是非常低的,特别在处理大 ...

  7. mongodb 索引建立问题

    mongodb  索引建立问题 1.主从库索引建立不是同步建立: MONGODB 2.6.6 版本,索引建立并不是同步的,而是主库建立完成后,从库接着建立索引.     不知是3.0版本是否也一样,以 ...

  8. MongoDB索引原理和具体使用

    1. MongoDB 索引是用来干嘛? 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录. 这种扫描全集合的查询效率是非常 ...

  9. MongoDB索引策略和索引类型

    1. MongoDB索引策略和索引类型–简介 MongoDB是一个开放源代码,面向文档的跨平台数据库,它使用C ++开发,并且是最流行和使用最广泛的NoSQL类型数据库之一. 它可在具有键-值对的类J ...

  10. MongoDB索引,性能分析

    索引的限制: 索引名称不能超过128个字符 每个集合不能超过64个索引 复合索引不能超过31列 MongoDB 索引语法 db.collection.createIndex({ <field&g ...

最新文章

  1. Hadoop(HDFS、YARN、HBase、Hive和Spark等)默认端口表
  2. .Net中简单实现发送邮件
  3. python中io.textio_Python文件读写概述(IO操作、文件读写、stringiobytesio、序列化),python,的,小,总结,StringIOBytesIO...
  4. POJ - 2774 Long Long Message(后缀数组)
  5. 第32讲:实时处理利器 mitmproxy 的使用
  6. C#将dataGridView中显示的数据导出到Excel(大数据量超实用版)
  7. 用Portainer或UI for Docker可视化管理树莓派容器
  8. Oracle分析函数之Rank函数
  9. iphone越狱-------平刷回越狱前(未越狱)状态
  10. CWMP (TR-069)技术介绍
  11. SWMM模型代码LID(Low Impact Development)模块分析
  12. 基于SSM的办公人员管理系统的设计与实现(附源码)
  13. 计算机二级常用口诀,2017计算机二级考试重点
  14. java memcmp_【转】 memcmp源码实现
  15. 华为云服务的使用方法详解--以照片备份与恢复为例
  16. fatal: detected dubious ownership in repository at ‘/home/
  17. win10 office2021+mathtype安装配置
  18. 幕客学习CSS3全面基础知识点
  19. iOS爱康APP组件化架构
  20. 【Java设计模式】Java设计模式之(十九)装饰器模式(Decorator Pattern)

热门文章

  1. [科技部与你共成长] 倒牛奶
  2. fabric-ca 登记身份时报Error: Response from server: Error Code: 20 - Authentication failure
  3. Python使用BeautifulSoup爬取网页中主体部分的内容,并导出为pdf格式
  4. 转载—android 媒体库数据更新解决办法总结
  5. JS格式化时间之后少了8个小时
  6. 开发者神器!Windows上最强大的虚拟桌面工具-Dexpot
  7. 关于Java静态属性初始化
  8. IDEA快捷键eclipse版(有自定义部分)
  9. 怎么调出matlab的函数,matlab定义函数【搞定方法】
  10. [USACO08DEC]拍头Patting Heads 数学 BZOJ 1607