mongo——索引三

一、索引规则

(1)索引可以大大减少要处理的文档数量,没有适当的索引,唯一满足条件的查询方式就是扫描全部文档,直到找到满足条件的查询。

(2)唯一的单键索引将会用来处理查询。对于包含多个键查询,包含这些键的复合索引是最好的解决方案

(3)如果有一个复合索引a-b,那么a上的单键索引就是多余的,b上的不多余

(4)复合索引的键值顺序很重要

example1:

db.products.find({'details.manufacturer':'Acme', 'pricing.sale':{$lt : 7500}})

如果details.manufacturer和pricing.sale各自有单键索引,需要单独遍历每个数据结构,找到它们的磁盘位置,计算交集。

如果建立了details.manufacturer和pricing.sale的复合索引,查询优化器需要找到索引中制造商manufacturer是Acme并且价格是7500的第一个入口。从那里开始,结果可以使用连续的扫描查找出来。

注意:(1)索引键值的顺序非常重要。如果我们定义的复合索引第一个值是price,第二个是manufacturer,那么查询效率就会非常低。键值必须按照出现的顺序比较,先找到7500,然后扫苗小于7500的文档判断是否是Acme公司生成的,假设有10000万个产品,所有价格低于10000,并且按价格均匀分布。这种情况需要扫描7500万个索引。

索引效率

如果某个集合包含10个索引,那么除了编写文档,每次插入都需要单独修改10个数据结构。这适用于任何写操作,无论是删除文档,还是因为空间不足挪动文档或者更新文档的索引键。对于读取密集型的应用,索引的成本是可以理解的。知道索引有成本,所以必须仔细选择。这意味着确保所有的索引都会被使用,不会有冗余。

第二个问题,即使所有的索引都建设得恰当,也可能无法加快查询,这会在索引和数据集没有加载到RAM的时候发生。

当使用默认的MMAPV1存储引擎时,使用系统调用mmap()方法,mongodb告诉os把所有的数据文件映射到内存中。但WiredTiger引擎使用了不同的方式,这一点上,包含所有文档,集合和索引的数据文件,被os加载和移除RAM,都按照4KB大小数据移动,这个数据块称为内存页。无论是否需要页上的数据,os都必须确保RAM中的数据页可用。如果没有,就会出现页面错误的异常,这会告诉内存管理器,要从磁盘加载数据到RAM里。

无论何时修改内存数据,比如写数据时,这些修改都会被os异步写入磁盘。写入时更快,因为直接操作内存,因此将磁盘的访问量降到最低。但是如果数据文件无法全部进入RAM就会出现页面错误。这意味着os将会频繁访问磁盘,大大降级读写速度。最坏的情况下,数据大小变得比RAM容量大很多。一种情形就是无论读写,数据都必须从磁盘或者向磁盘写入数据。这种情况有个专业的称呼:“颠簸”,它会严重导致性能变慢。

幸运的是,这种情形相对容易避免。至少我们可以确保索引加入RAM里,这也是为什么不创建不需要的索引的原因。设置的索引越多,就需要越多的RAM来维护这些索引。沿着相同的路线,每个索引应该只包含需要的键值。有时候也会需要3个键值的复合索引,但是需要知道它比单键索引需要更多的空间。创建一个或者2个字段索引,是为频繁地查询创建覆盖索引。覆盖索引是所有的查询都可以使用一个查询来满足查询的索引,让查询变得非常快。

 

 

 

多键索引

{name:"ww" , tags:["tools","soil"]}

如果在tags上创建索引,每个文档tags数组的值会出现在索引里,就意味着针对这些数组任意值在索引上的查询都会定位到文档上。这是多键索引背后的思想:多个索引入口或者键值,引用同一个文档。

哈希索引

db.tablename.createIndex({name:"hashed"})

限制:等值查询相似,不支持范围查询; 不支持多键哈希; 浮点数在哈希之前转换为整数,因此4.2和4.3有相同的哈希索引

为什么要使用:哈希索引的入口是均匀分布的。换句话说,当有键值数据不均匀分布时,哈希函数可以创建均匀性。‘Apple Pie’和“Artichoke Ravioli”在哈希索引中就不会相邻了。索引数据的位置已经变化了。它对于分片集合非常有用,分片索引决定文档分配到哪个片中。如果分片索引基于增长的值,比如mongo OIDs ,那么新创建的文档只会插入单个片中,除非索引是哈希的。

深入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小卒曹阿瞒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值