当前位置:网站首页>分布式文档存储数据库之MongoDB索引管理
分布式文档存储数据库之MongoDB索引管理
2020-11-10 01:15:00 【程序猿欧文】
我们在某个字段构建好索引以后,用户在写数据时,通常会额外多一次写io;对于写请求,在没有索引的情况,用户只需要写一次io,有了索引用户每写一条数据,都会对应有一次写索引的io;这样一来在一定程度上对用户的写性能会有影响;但通常我们构建索引都是在读多写少的场景中使用;在写请求不是特别多的场景其实多一次写io,比起读请求的压力我们是可以接受的;更何况有些数据库支持延迟写索引,所谓延迟写索引是指用户在插入数据时,它不立即写索引,而是等一段时间再写,这样一来就有效的降低写索引对用户的写请求性能的影响;
前文我们聊到了MongoDB的简介、安装和对collection的CRUD操作,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13941797.html;今天我们来聊下mongodb的索引;
1、为什么要有索引?索引的作用是干嘛的?
我们知道mongodb通常应用在一些web站点,数据量非常大的场景中;在大数据的场景中,对于我们要查询一个数据,mongodb是否能够快速的响应结果就变得尤为的重要;这也是索引存在的意义;索引就是用来帮助我们在很大的数据集中快速查询我们想要的数据;通常我们在mongodb中插入一条数据时,mongodb会自动给我们添加一个_id的字段,这个字段是mongodb内部自己维护,通常情况我们都不会去管它;在关系型数据库中,我们可以在单个字段上构建索引,也可以在多个字段上构建索引,之所以要在多个字段构建索引是因为我们的查询条件很可能用到的字段不只一个;所以我们构建索引的原则是根据查询条件来构建;比如我们要查询年龄大于30的用户有哪些,我们就可以把索引构建在年龄这个字段上,构建在其他字段上,对于我们要查询年龄大于30这个条件来讲是没有意义的;所以构建索引通常我们会去了解用户最常的查询,在用户最常查询的字段上构建索引,这样可以有效提高用户的查询;对于mongodb也是一样的,索引的存在就是为了提高我们的查询;
2、为什么索引能够帮助我们快速查找呢?
首先索引是按照我们指定的字段来构建,构建索引就是把我们指定的字段抽取出来,然后提前排好序(或者按照一定规律的方式排列好),然后保存为另外一个collection;用户在查找数据时,mongodb首先会去找索引,看看用户的条件是否和索引匹配,能够匹配,索引就能告诉用户要查询的数据在那个地方,这样就很快的找到用户查询的数据;假如我们构建的索引没有匹配用户的查询,那么用户的查询会以遍历的方式去查找,这样一来无形之中速度就变慢了(原本不加索引,直接遍历,现在有索引,要先查索引,没有命中,还要遍历);所以构建索引,如果一定是数据量很大的情况才构建,数据量小,构建索引不但不会帮助我们快速的查找内容,反而会拖慢我们的查询速度;其次在很大的数据量上,如果索引构建的字段没有被查询命中,那么我构建的索引就无意义;
3、索引在一定程度上是要影响用户写的性能
我们在某个字段构建好索引以后,用户在写数据时,通常会额外多一次写io;对于写请求,在没有索引的情况,用户只需要写一次io,有了索引用户每写一条数据,都会对应有一次写索引的io;这样一来在一定程度上对用户的写性能会有影响;但通常我们构建索引都是在读多写少的场景中使用;在写请求不是特别多的场景其实多一次写io,比起读请求的压力我们是可以接受的;更何况有些数据库支持延迟写索引,所谓延迟写索引是指用户在插入数据时,它不立即写索引,而是等一段时间再写,这样一来就有效的降低写索引对用户的写请求性能的影响;

上图主要描述了索引和文档的关系,在索引里的数据通常是我们指定的字段,用特定的排列方式组织在一起,在用户查询某个数据时,就能够很快的从索引中拿到对应文档的位置,从而不用每个文档挨着遍历;这也是索引能够帮助我们快速查找的原因吧;
4、索引类型
索引是有类型的,不同类型的索引在内部组织索引的方式各不相同,不同类型的索引给我们查询带来的效果也不同;常见的索引类型有b+ tree(平衡树索引),hash索引、空间索引、全文索引等等;在mongodb中索引也有很多类型,不同的是我们上面说的索引类型,b+ tree,hash索引这些都是从索引内部组织结构来描述;在mongodb中的索引我们是从索引构建的位置来描述;mongodb中的索引有单键索引、组合索引、多键索引、空间索引、文本索引和hash索引;所谓单键索引是指构建在一个字段上的索引;组合索引指构建在多个字段上的索引;多键索引指将索引构建在一个键的值是一个子文档的字段上;我们知道文档和文档是可以嵌套的,这也意味着一个文档内部可以引用另一个文档,一个文档中的某个键对应的值也可以是另外一个子文档;我们把这种索引构建在一个文档中的某个键是一个子文档的某个字段上的索引叫做多键索引,它和单键索引不是对应的;空间索引指基于位置查询的索引,但通常这种索引只有用到特定的方法来查询时,它才会生效,比如使用基于空间位置的函数;文本索引指支持搜索整个文档中的文本信息,通常这种索引我们也叫全文索引;hash索引指把某个字段的值做hash计算后组织的索引;这种索引有个特点就是时间复杂度是o(1);不管数据有多少,在查找数据时所用到的时间都是一样的;之所以时间复杂度是o(1),原因是hash计算每一个值都是唯一的;这种索引的查找方式有点类似键值查找,不同的是hash背后对应的是一个hash桶,先找到hash桶,然后查找到对应的hash值;hash索引和b+树索引最大的区别是,b+树索引可以查询一个范围,因为树状索引通常是把数据组织成一个有序的结构,而hash索引不能,hash索引只能查找一个精确的值,不能查找一个范围;因为hash索引背后对应的是一个hash值,每个hash值可能都不在一个hash桶,所以我们假如要查询年龄大于30岁的用户,用hash索引就不适合,因为30和31的hash值可能就不在一个hash桶上;
5、在mongodb数据库上创建索引
准备数据
> use testdbswitched to db testdb> for (i=1;i<=1000000;i++) db.peoples.insert({name:"people"+i,age:(i%120),classes:(i%20)})WriteResult({ "nInserted" : 1 })> db.peoples.find().count()1000000> db.peoples.find(){ "_id" : ObjectId("5fa943987a7deafb9e543326"), "name" : "people1", "age" : 1, "classes" : 1 }{ "_id" : ObjectId("5fa943987a7deafb9e543327"), "name" : "people2", "age" : 2, "classes" : 2 }{ "_id" : ObjectId("5fa943987a7deafb9e543328"), "name" : "people3", "age" : 3, "classes" : 3 }{ "_id" : ObjectId("5fa943987a7deafb9e543329"), "name" : "people4", "age" : 4, "classes" : 4 }{ "_id" : ObjectId("5fa943987a7deafb9e54332a"), "name" : "people5", "age" : 5, "classes" : 5 }{ "_id" : ObjectId("5fa943987a7deafb9e54332b"), "name" : "people6", "age" : 6, "classes" : 6 }{ "_id" : ObjectId("5fa943987a7deafb9e54332c"), "name" : "people7", "age" : 7, "classes" : 7 }{ "_id" : ObjectId("5fa943987a7deafb9e54332d"), "name" : "people8", "age" : 8, "classes" : 8 }{ "_id" : ObjectId("5fa943987a7deafb9e54332e"), "name" : "people9", "age" : 9, "classes" : 9 }{ "_id" : ObjectId("5fa943987a7deafb9e54332f"), "name" : "people10", "age" : 10, "classes" : 10 }{ "_id" : ObjectId("5fa943987a7deafb9e543330"), "name" : "people11", "age" : 11, "classes" : 11 }{ "_id" : ObjectId("5fa943987a7deafb9e543331"), "name" : "people12", "age" : 12, "classes" : 12 }{ "_id" : ObjectId("5fa943987a7deafb9e543332"), "name" : "people13", "age" : 13, "classes" : 13 }{ "_id" : ObjectId("5fa943987a7deafb9e543333"), "name" : "people14", "age" : 14, "classes" : 14 }{ "_id" : ObjectId("5fa943987a7deafb9e543334"), "name" : "people15", "age" : 15, "classes" : 15 }{ "_id" : ObjectId("5fa943987a7deafb9e543335"), "name" : "people16", "age" : 16, "classes" : 16 }{ "_id" : ObjectId("5fa943987a7deafb9e543336"), "name" : "people17", "age" : 17, "classes" : 17 }{ "_id" : ObjectId("5fa943987a7deafb9e543337"), "name" : "people18", "age" : 18, "classes" : 18 }{ "_id" : ObjectId("5fa943987a7deafb9e543338"), "name" : "people19", "age" : 19, "classes" : 19 }{ "_id" : ObjectId("5fa943987a7deafb9e543339"), "name" : "people20", "age" : 20, "classes" : 0 }Type "it" for more> it{ "_id" : ObjectId("5fa943987a7deafb9e54333a"), "name" : "people21", "age" : 21, "classes" : 1 }{ "_id" : ObjectId("5fa943987a7deafb9e54333b"), "name" : "people22", "age" : 22, "classes" : 2 }{ "_id" : ObjectId("5fa943987a7deafb9e54333c"), "name" : "people23", "age" : 23, "classes" : 3 }{ "_id" : ObjectId("5fa943987a7deafb9e54333d"), "name" : "people24", "age" : 24, "classes" : 4 }{ "_id" : ObjectId("5fa943987a7deafb9e54333e"), "name" : "people25", "age" : 25, "classes" : 5 }{ "_id" : ObjectId("5fa943987a7deafb9e54333f"), "name" : "people26", "age" : 26, "classes" : 6 }{ "_id" : ObjectId("5fa943987a7deafb9e543340"), "name" : "people27", "age" : 27, "classes" : 7 }{ "_id" : ObjectId("5fa943987a7deafb9e543341"), "name" : "people28", "age" : 28, "classes" : 8 }{ "_id" : ObjectId("5fa943987a7deafb9e543342"), "name" : "people29", "age" : 29, "classes" : 9 }{ "_id" : ObjectId("5fa943987a7deafb9e543343"), "name" : "people30", "age" : 30, "classes" : 10 }{ "_id" : ObjectId("5fa943987a7deafb9e543344"), "name" : "people31", "age" : 31, "classes" : 11 }{ "_id" : ObjectId("5fa943987a7deafb9e543345"), "name" : "people32", "age" : 32, "classes" : 12 }{ "_id" : ObjectId("5fa943987a7deafb9e543346"), "name" : "people33", "age" : 33, "classes" : 13 }{ "_id" : ObjectId("5fa943987a7deafb9e543347"), "name" : "people34", "age" : 34, "classes" : 14 }{ "_id" : ObjectId("5fa943987a7deafb9e543348"), "name" : "people35", "age" : 35, "classe.........
版权声明
本文为[程序猿欧文]所创,转载请带上原文链接,感谢
https://my.oschina.net/mikeowen/blog/4710410
边栏推荐
- CUDA_全局内存及访问优化
- Exhibition cloud technology interpretation | in the face of emergencies, how does app do a good job in crash analysis and performance monitoring?
- jt-day10
- 编码风格:Mvc模式下SSM环境,代码分层管理
- C++异常实现机制
- JS solves the problem of automatic pagination in browser printing
- 初级工程师如何在职场生存
- 编码风格:Mvc模式下SSM环境,代码分层管理
- C++ exception implementation mechanism
- How SSL certificate and public IP address affect SEO
猜你喜欢
![[Python learning manual notes] 001. Preface to Python](/img/c0/b4d34272d3f845ac717d48c669d974.jpg)
[Python learning manual notes] 001. Preface to Python

Optimization of commodity backstage system
![Python中[:]与[::]的用法](/img/3b/00bc81122d330c9d59909994e61027.jpg)
Python中[:]与[::]的用法

SRM系统是什么系统?SRM供应商管理系统功能

YouTube subscription: solve the problem of incomplete height display of YouTube subscription button in pop-up window

JS solves the problem of automatic pagination in browser printing

mongodb内核源码实现、性能调优、最佳运维实践系列-command命令处理模块源码实现一

实验2

Interviewer: what are cache penetration, cache avalanche and cache breakdown?

How SSL certificate and public IP address affect SEO
随机推荐
JS solves the problem of automatic pagination in browser printing
Seam engraving algorithm: a seemingly impossible image size adjustment method
自己上手写性能测试工具(二)
算法模板整理(一)
C/C++编程笔记:C语言开发坦克大战!纪念我们逝去的小霸王游戏
Error running app:Default Activity not found 解决方法
Notes on Python cookbook 3rd (2.2): String start or end match
CUDA_ Host memory
Bifrost 位点管理 之 异构中间件实现难点(1)
消防知识线上答题活动小程序复盘
假如需要一百万个对象
[leetcode] 92 integer inversion
leetcode之最后一个单词的长度
CUDA_常量内存
Gets the property value of a column in the list collection object
Explanation of Z-index attribute
获取List集合对象中某一列属性值
SQL case conversion, remove the space before and after
leetcode之最后一个单词的长度
Hengxun Technology: the way to deal with server downtime