当前位置:网站首页>分布式文档存储数据库之MongoDB索引管理
分布式文档存储数据库之MongoDB索引管理
2020-11-10 01:15:00 【程序猿欧文】
前文我们聊到了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
边栏推荐
- 利用尾巴作为时间序列进行处理来识别鲸鱼
- Hengxun Technology: the way to deal with server downtime
- Python cookbook 3rd note (2.1): using multiple qualifiers to split strings
- day85:luffy:购物车根据有效期不同切换价格&购物车删除操作&价格结算&订单页面前戏
- Coding style: SSM environment in MVC mode, code hierarchical management
- Can public IP address and SSL certificate improve SEO?
- YouTube subscription: solve the problem of incomplete height display of YouTube subscription button in pop-up window
- CUDA_常量内存
- jt-day10
- Visit 2020 PG Technology Conference
猜你喜欢
痞子衡嵌入式:RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计
恒讯科技浅谈:出现服务器宕机的处理方式
Incomplete Polyfill of proxy
Top 5 Chinese cloud manufacturers in 2018: Alibaba cloud, Tencent cloud, AWS, telecom, Unicom
day85:luffy:购物车根据有效期不同切换价格&购物车删除操作&价格结算&订单页面前戏
Centos7 operating system security hardening series (2)
利用尾巴作为时间序列进行处理来识别鲸鱼
获取List集合对象中某一列属性值
Unity使用transform.Rotate进行三维旋转角度出现偏差
Must see! RDS database all in one
随机推荐
CUDA_ constant memory
One image can hold 16x16 words! ——Transformers for large scale image scaling recognition (a brief review of ICLR 2021 papers)
CUDA_ Memory model
Detach ()
一个名为不安全的类Unsafe
痞子衡嵌入式:RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计
算法模板整理(一)
SQL case conversion, remove the space before and after
No space left on device
z-index属性详解
Brief analysis of LinkedList source code
CUDA_存储器模型
JS label syntax jumps out of multiple loops
完美日记母公司逸仙电商招股书:重营销、轻研发,前三季度亏11亿
Notes on Python cookbook 3rd (2.2): String start or end match
eleven point nine
[python学习手册-笔记]001.python前言
Make a home page
获取List集合对象中某一列属性值
飞鸽传书局域网找不到其他人的问题解决