Implementation Tips | Tips #22:Use indexes to do more with less memory

本文探讨了MongoDB中如何通过创建索引来显著提高查询效率。对比了未使用索引时需要加载大量数据到内存的情况,并详细解释了索引的工作原理及如何减少查询所需加载的页面数。

原版书<<50 Tips and Tricks for MongoDB Developers>> 地址:http://oreilly.com/catalog/0636920019893

皮皮书屋下载地址:http://www.ppurl.com/2011/05/50-tips-and-tricks-for-mongodb-developers.html

本书的所有翻译地址:http://blog.youkuaiyun.com/crazyjixiang/article/category/858638

翻译目的:MongoDB资料国内很少,书就更不必说了,借助对MongoDB的理解为大家做点贡献,如果有翻译有误的地方请指正,不能误入子弟,谢谢!

译者: Crazybaby


对Tip# 22 翻译如下:


首先让我们看张查询请求的图:


参照这张图,假设我们都在这一页上,对于这本书,一页大小的内存为4KB,尽管这不是普遍如此。

我们就比方说有一台拥有256G数据和16G内存的PC,假设大部分数据都在一个集合中然后你将查询这个结合,MongoDB这时会怎么做?

MongoDB会从硬盘加载一个集合的第一页到内存中,然后和将要查询的数据进行比较。然后继续加载页再进行比较,如此循环直到256G数据全部加载过,这些步骤不能采取任何捷径。MongoDB不可能知道在匹配时因该查询哪个文档(document),所以它必须把每个文档都遍历一遍,因此,它将需要载入256G数据到内存中(OS需要小心交换内存中旧的分页因为它需要新的空间给新的页面).这需要花费很长很长的时间。

我们怎么避免每次查询都要载入256G的数据到内存呢?我们可以给MongoDB某个字段(Field)创建一个索引,这样MongoDB将会针对那个字段创建一个集合值的树,请看下图:




树中的任意索引将直接指向文档中的值x.这树只是包含了指向文档的指针,而不是文档自己,也就是说这个索引比整个集合小很多。


当你需要查询包含x的一部分时,MongoDB将会注意x上有索引然后将会在这个值的树上进行搜索,现在就不是查询整个文档了。MongoDB会说:"如果查询的值比树的节点值大或者小? 大则走树的右边,小则走树的左边".然后按照这个规则继续下去直到找到这个值或者这个值不存在。如果找到这个值,它将会指向实际文档,然后载入文档的页放入内存中然后再返回。见图:




试想我们查询需要遍历整个文档或者查询两个的集合中。如果我们不用索引,我们必须从磁盘载入64亿页进入内存:

页大小: 256G / (4KB/page) = 64 million pages

试想我们的索引有80G ,然后索引有20亿页大小为:
80G / (4K/page) = 20 million pages

无论如何,索引是按顺序的,也就是说我们不需要遍历每个入口:我们只需要载入需要的节点.多少?

ln(20,000,000) = 17 pages

从 64,000,000 降到 17!



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值