您的位置:首页 > 数据库 > Mongodb

Mongodb-索引

2016-03-08 10:27 330 查看
索引就是用来加速查询的,数据库索引与书籍的索引类似:有了索引,就不需要翻遍整本书,数据库直接在索引中查找就好了,这样使得查找速度提高了几个数量级。在索引中找到目标条目后,可直接跳转到目标文档处。更为极端的说,创建数据库索引就像如何组织书的索引一样,但你的优势是知道今后会做何种查询,哪些内容是需要被快速定位的……^_^

创建索引

当查询中仅使用一个键时,可以对该键建立索引,如果我们欲对User中的name键建立索引:
db.User.ensureIndex({"name", 1})
但是当对name建立索引后,却对其他查询不起作用,即便其他查询中也包含了name键。

实践表明,一定要创建查询中用到的所有键的索引,否则,服务器就会做表扫描,这在表特别大的情况下会非常耗时。

一组值为1或-1 的键,表示索引创建的方向,如若索引只有一个键,那么方向无关紧要。

对于{“username”: 1, “age”: -1}这样的索引,Mongodb是按照用户名升序,同名按年龄逆序组织文档的,这对{“username”: 1, “age”: -1}的查询会做优化,但是对{“username”: 1, “age”: 1}的查询”然并卵“,此时你还需要给它创建相应的{“username”: 1, “age”: 1}的索引。

一般来说,创建的索引如果有N个键,那么对前几个键的查询都会是有帮助的。比如有这样的索引:{“a1”:1,”b1”:1,”c1”;1,……,”z1”:1},那么实际上你就具备了{“a1”:1},{“a1”:1,”b1”:1},{“a1”:1,”b1”:1,”c1”:1}等的索引,但是如果顺序变了{“b1”:1,”a1”:1,”c1”:1}这样是不可行的。

Mongodb的查询优化器会重排查询项的顺序,以便利用索引

创建索引的缺点就是每次创建、删除、更新时都会产生额外的开销,这是因为数据库不仅需要执行这些操作,还需要在索引中标记这些操作的集合。因此,尽可能少的创建索引,每个集合的最大索引数是64个。

创建索引需要考虑的问题

会做什么样的查询?查询需要使用到哪些键?

每个键的索引方向是怎么样的?

如何应对扩展,有没有种不同的键的排列可以使尽可能多的数据保留在内存中?

索引内嵌文档中的键

其实为内嵌文档创建索引和为普通文档创建索引是没有什么区别的。

db.User.ensureIndex({"extension.mods", 1})


为排序做索引

随着集合的增长,需要针对查询中大量的排序做索引,如果没有索引的键调用索引,Mongodb是会将所有数据提取到内存中来做排序的,无索引排序是有上限的,那就是不能做T级别以上的数据的无索引排序。一旦无索引排序的量大过上限,那么就会报错,索引当数据量过大的时候应当考虑为排序做索引。

索引名称

集合中的每一个索引都对应一个字符串的名字,来唯一标示索引。服务器根据这个名字来删除和操作索引。

对于{“name”:1, “age”:1}的索引,它的唯一索引名是“name_1_age_1”

我们也可以通过ensureIndex来指定自定义的名字。

db.user.ensureIndex({"a":1,"b":1},{"name":"my_index"})
当我们创建的索引非常复杂时,最好使用自定义的名字,因为索引的名字也是有字符个数的限制的。

唯一索引

唯一索引可以确保集合的指定键都有唯一的值,例如:

db.people.ensureIndex({"name":1},{"unique":true})
当设置唯一索引后,对于people集合的name键而言,每个值应该是唯一的,当插入重复键的时候将会报错。

还有一种情况,当我们想要为name创建索引时,可能已经有了重复的键,那么此时创建唯一索引将会是失败的,使用dropDups选项可以避免这种情况,它会保留发现的第一个文档,而删除所有重复的文档。

对于复合唯一索引而言,单个键的值是可以重复的,但是整体是不可以重复的。

本文仅为本人阅读相关资料的笔记,如有不足之处,还请指出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mongodb 索引 数据库