首页 > 数据库 >MongoDB 索引原理与索引优化

MongoDB 索引原理与索引优化

时间:2022-12-23 23:01:12浏览次数:36  
标签:executionStats MongoDB 查询 索引 IO 磁盘 优化

转载请注明出处:

1.MongoDB索引

  索引通常能够极大的提高查询的效率, 如果没有索引, MongoDB 在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的, 特别在处理大量的数据时, 查询可以要花费几十秒甚至几分钟, 这对网站的性能是非常致命的。

  索引是特殊的数据结构, 索引存储在一个易于遍历读取的数据集合中, 索引是对数据库表中一列或多列的值进行排序的一种结构。

2.MongoDB索引说明

  索引数据通过 B 树来存储,从而使得搜索的时间复杂度为 O(logdN) 级别的(d 是 B 树的度, 通常 d 的值比较大,比如大于 100),比原先 O(N) 的复杂度大幅下降。这个差距是惊人的,以一个实际例子来看,假设 d=100,N=1亿,那么 O(logdN) = 8, 而 O(N) 是 1亿。是的,这就是算法的威力。

  索引本身是在高速缓存当中,相比磁盘 IO 操作会有大幅的性能提升。(需要注意的是,有的时候数据量非常大的时候,索引数据也会非常大,当大到超出内存容量的时候,会导致部分索引数据存储在磁盘上,这会导致磁盘 IO 的开销大幅增加,从而影响性能,所以务必要保证有足够的内存能容下所有的索引数据)

  当然,事物总有其两面性,在提升查询速度的同时,由于要建立索引,所以写入操作时就需要额外的添加索引的操作,这必然会影响写入的性能,所以当有大量写操作而读操作比较少的时候,且对读操作性能不需要考虑的时候,就不适合建立索引。当然,目前大多数互联网应用都是读操作远大于写操作,因此建立索引很多时候是非常划算和必要的操作。

3.为什么使用B-Tree

B树有以下特点

  • B树在查询中的比较是在内存中完成的,相比磁盘IO的速度,内存中的比较耗时几乎可以忽略。所以只要树的高度足够低,IO次数足够少,就可以提升查找性能。

  • B树为了插入一个元素,多个节点发生了连锁改变,会有一定的性能损耗,但也正因为如此,B树能够始终维持多路平衡。这也是B树的另外一大优势:自平衡。

  • 查找的元素在不同的结点(根结点、中间结点、叶子结点),性能会有一定差别,因此查询性能不稳定。

  • 范围查找性能不高。

  • 我们知道二叉查找树查询的时间复杂度是O(logN),查找速度最快和比较次数最少,既然性能已经如此优秀,但为什么实现索引是使用B-Tree而不是二叉查找树,关键因素是磁盘IO的次数。

  磁盘读取依靠的是机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加就是一次磁盘IO的时间,大概9ms左右。这个成本是访问内存的十万倍左右。正是由于磁盘IO是非常昂贵的操作,所以数据库性能优化的核心思想是降低磁盘IO次数。

  说明: 普通的机械盘HDD一次磁盘IO的时间大概是9ms;  普通SSD一次磁盘IO耗时大概是0.2ms(IOPS:5000);  PCIe卡一次磁盘IO耗时大概是0.05ms(IOPS:20000);

  从二叉树的查找过程了来看,最坏的情况下磁盘IO的次数由树的高度来决定。要减少磁盘IO的次数就必须要压缩树的高度,让瘦高的树尽量变成矮胖的树,所以B-Tree就在这样伟大的时代背景下诞生了。

4.MongoDB 索引优化:explain

    语法

db_name.table_Name.find({query}).explain(cond)

    参数

名称描述
db_name 数据库名
table_Name 集合名
query 查询条件
cond 查询计划所使用的参数

    返回值

参数含义
plannerVersion 查询计划版本
namespace 要查询的集合
indexFilterSet 是否使用索引
parsedQuery 查询条件,此处为x=1
winningPlan 最佳执行计划
stage 查询方式,见下表
filter 过滤条件
direction 搜索方向
rejectedPlans 拒绝的执行计划
serverInfo MongoDB服务器信息

    stage说明

参数含义
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索文档
SHARD_MERGE 合并分片结果
IDHACK 针对 _id 进行查询

  2.executionStats:executionStats会返回执行计划的一些统计信息

 

参数含义
executionSuccess 是否执行成功
nRetured 返回的文档数
executionTimeMillis 执行耗时
totalKeysExamined 索引扫描次数
totalDocsExamined 文档扫描次数
stage 扫描方式,具体可选值与上下的相同
nRetured 查询document获得数据的时间
executionTimeMillsEstimate 检索document获得数据的时间
inputStage.executionTimeMillisEstimate 该查询扫描文档index所用时间
works 工作单元数,一个查询会分解成小的工作单元
advanced 优先返回的结果数
docsExamined 文档检查数目,与totalDocsExamined一致,检查了总共的document个数,从而返回上面的nReturned数量

 

  在实际分析索引问题是否最优的时候,主要查看executionStats.totalKeysExamined、

  executionStats.totalDocsExamined、executionStats .nReturned三个统计项,如果存在以下情况则说明索引存在问题,可能索引不是最优的:

  1. executionStats.totalKeysExamine远大于executionStats .nReturned

  2. executionStats. totalDocsExamined远大于executionStats .nReturned

 

 

标签:executionStats,MongoDB,查询,索引,IO,磁盘,优化
From: https://www.cnblogs.com/zjdxr-up/p/17001798.html

相关文章

  • cucumber:使用cucumber-reporting 插件优化HTML report
    承接上一篇:API测试框架:cucumber+springBoot+restAssured原始的cucumberreport比较粗糙,如图下: 我们可以通过cucumber-reporting插件对报告进去优化,集成介绍如下:1)......
  • 搜索引擎的设计与实现(源码+PPT+论文)
    毕业设计说明书搜索引擎的设计与实现搜索引擎的设计与实现摘要: 我们处在一个大数据的时代,伴随着网络信息资源的庞大,人们越来越多地注重怎样才能快速有效地从海量的网络信息......
  • 通过地址和索引实现数组
    CPU会把基址寄存器+变址寄存器的值解释为实际查看的内存地址。变址寄存器的值就相当于高级编程语言程序中数组的索引功能。数组是指同样长度的数据在内存中进行连续排列的......
  • 使用 REST 访问 MongoDB 数据
    本指南将引导您完成创建应用程序的过程,该应用程序通过基于超媒体休息的前端。您将构建什么您将构建一个Spring应用程序,该应用程序允许您创建和检索存储在​​Person​​蒙......
  • mongodb查看数据库和表的信息
    mongodb查看数据库和表的信息mongodb查看数据库和表的方法比较简单,在为这里推荐使用stats的方法,直观并且详细。1、查看数据库db.stats();1输出:{"db":"sirius","colle......
  • 唯一索引
    ALTERTABLEt_factor_weightADDUNIQUEfid_fac_sym_unique_index(`fund_id`,`factor_name`,`symbol`);ALTERTABLEt_factor_target_positionADDUNIQUEfid_factor_......
  • SpringBoot2.x系列教程51--NoSQL之SpringBoot整合MongoDB
    SpringBoot2.x系列教程51--NoSQL之SpringBoot整合MongoDB作者:一一哥一.MongoDB1.MongoDB简介MongoDB一词来自于英文单词“Humongous”,中文含义为“庞大”,是由C++语言编写......
  • MongoDB 3.x版本无法找到mongod.cfg文件以及无法开启远程访问的解决方案
    本篇博客主要在于解决mongodb3.6版本开启远程访问,并非mongodb软件安装指南。如果你安装后可以看到bin\mongod.cfg文件,那么无需看此博客这里附一条安装方法的连接https://bl......
  • 【目标检测/实例分割】常用优化方法
    一、OHEN1.目的:区分难分样本2.方法:多学习难例对于一次SGD迭代:先计算出特征图,可读RoI网络对所有RoI执行前向计算并计算每个RoI的损失,然后选择hardRo......
  • MySQL-索引优化
    回顾聚簇索引,官网的定义在这里。聚簇索引无法显示创建,存储引擎会根据一定的规则自动创建,具体规则优先级是:主键--》非空唯一索引--》隐藏列rowid**InnoDB表的主键列应该......