日期:2014-05-16  浏览次数:20401 次

MongoDB初探-细说索引

一、索引操作

索引是为了优化查询速度而生,MongoDB的索引和其他关系型数据库,比如MySQL,Oracle等的索引几乎相同,对于它们的索引优化经验同样适用于MongoDB。

1、创建索引

MongoDB中建立索引是通过ensureIndex操作完成的。下面测试了在使用索引和不使用索引下的性能差别,使用explain函数进行查询性能分析。

插入测试数据:


不使用索引的查询:


使用索引的查询:


由以上测试可见,使用恰当的索引查找可以大大优化查询效率。

2、删除索引


索引的元信息存储在每个数据库的system.indexes集合中,该集合为保留集合,不能对其插入或删除文档。
操作只能通过ensureIndex或dropIndexes进行。

二、唯一索引

唯一索引可以确保集合的每一个文档的指定键都有唯一值。MongoDB建立唯一索引的方式如下:

db.person.ensureIndex({"name":1},{"unique":true})

如果没有对应的键,索引会将其作为null存储。所以,如果对某个键建立了唯一索引,但插入了多个缺少该索引键的文档,则由于文档包含null值而导致插入失败。

三、组合索引

通过为ensureIndex的第一个参数传入多个键值的文档来实现组合索引的建立。组合索引适用于对多条件查询的优化上,一般来说,如果索引包含N个键,则对于前几个键的查询都会有帮助。比如有个索引{"a":1,"b":1,"c":1,...,"z":1},实际上是有了{"a":1},{"a":1,"b":1},{"a":1,"b":1,"c":1}等的索引,但使用{"b":1},{"a":1,"c":1}等索引的查询则不会被优化。

四、地理空间索引

MongoDB的地理空间索引用于处理平面坐标的查询,对于查找离当前位置最近的N个场所非常适用,在LBS应用中经常使用。

1、创建空间索引

db.map.ensureIndex({"gps":"2d"})
"gps"键的值必须是某种形式的一对值:一个包含两个元素的数组或是包含两个键(键名随意)的内嵌文档,如下所示:
{"gps":[0,100]}
{"gps":{"x":0,"y":30}}
{"gps":{"latitude":0,"longitude":100}}
默认情况下,地理空间索引假设值的范围是-180~180,这对于处理经纬度非常方便,也可以设置其范围:
db.map.ensureIndex({"gps":"2d"},{"min":-360,"max":360})
2、查找

通过find函数查找:

将按照离坐标点(40,80)由近及远的方式将map集合的前5个文档返回。

db.map.find({"gps":{"$near":[40,80]}}).limit(5)

通过数据库命令查找:

db.runCommand({geoNear:"map",near:[40,80],num:5});
geoNear和使用$near的find普通查找类似,不过geoNear还会返回每个文档到查询点的距离。该距离以插入数据为单位,比如按照经纬度的角度插入,那距离就是经纬度。

具体其他空间索引的查找请参考MongoDB官方文档关于索引的介绍。

五、总结

对于索引的使用,要建立合适的索引,可以使用explain查看当前索引的效果。如果索引不适合当前业务需求的话,就要修改或删除,以免不必要或不恰当的索引对数据库操作产生影响。毕竟索引需要消耗内存和文件存储。对于索引要实时维护,不要索引每一个键。