索引是进步查问查问效率最无效的伎俩。索引是一种非凡的数据结构,索引以易于遍历的模式存储了数据的局部内容(如:一个特定的字段或一组字段值),索引会按肯定规定对存储值进行排序,而且索引的存储地位在内存中,所在从索引中检索数据会十分快。如果没有索引,MongoDB 必须扫描汇合中的每一个文档,这种扫描的效率非常低,尤其是在数据量较大时。
一、索引的基础知识
上面以关系型数据库 Oracle 为例,介绍索引的基本原理,如下图所示:
从上图能够看成,索引的实质其实就相当于是一本书的目录。当查问表中数据的时候,先查问目录(索引)中的行地址,再通过行地址查问到表中的数据,从而进步查问的性能。
下图阐明了在 MongoDB 中,索引在查问和排序中是如何工作的?
通过这个例子,能够分明的看到索引存储的是一个特定字段或者几个字段的汇合,并且依照肯定的法则排序。当创立汇合的时候,MongoDB 主动在 \_id 上创立一个唯一性索引,因为是唯一性的,所以能够避免反复的 \_id 值插入到汇合中。通过 getIndexes 能够查问到 MongoDB 汇合上的索引信息,如下图所示。
当没有索引的时候,通过查看执行打算,能够看到查问的过程,如下:查问:10 号部门,工资小于 3000 的文档。
那么如何创立一个简略的索引呢?留神从 mongoDB 3.0 开始 ensureIndex 被废除,今后都仅仅是 db.collection.createIndex 的一个别名。
当初在 deptno 和 sal 上建设一个索引,并从新查看执行打算:db.emp.createIndex({“deptno”:1,”sal”:-1})
留神:除了能够应用 explain() 生成执行计划外,还能够有几个可选的参数,如下:
.explain(“allPlansExecution”)
.explain(“executionStats”)
.explain(“queryPlanner”)
二、索引的类型一:单键索引(Single Field)
单键索引是最一般的索引,与_id 索引不同,单键索引不会主动创立。
筹备数据:db.testindex1.insert({"_id":1,"zipcode":1034,"location":{state:"NY",city:"New York"}})
在单个列上创立单键索引:db.testindex1.createIndex({"zipcode":1})
在嵌套的列上创立单键索引
db.testindex1.createIndex({"location:state":1})
在内嵌的文档上创立单键索引
db.testindex1.createIndex({"location":-1})
这样将会把 location 作为一个整体。
三、索引的类型二:多键索引(Multikey Index)
多键索引与单键索引创立模式雷同,区别在于字段的值。值具备多个记录,如数组。
如上图,基于汇合上的数组创立多键索引,且数组为内嵌文档。
筹备数据:db.testindex2.insertMany([{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9] },
{_id: 6, type: "food", item: "bbb", ratings: [ 5, 9] },
{_id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8] },
{_id: 8, type: "food", item: "ddd", ratings: [ 9, 5] },
{_id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5] }])
上面基于 ratings 列创立一个多键索引:
db.testindex2.createIndex({ ratings: 1} )
查问数组上为 5,9 的文档
db.testindex2.find({ ratings: [ 5, 9] } )
上面查看其执行打算
db.testindex2.find({ ratings: [ 5, 9] } ).explain()