索引是提升查询查询效率最有效的手段。索引是一种特殊的数据结构,索引以易于遍历的形式存储了数据的部份内容(如:一个特定的字段或一组字段值),索引会按必定规则对存储值进行排序,并且索引的存储位置在内存中,所在从索引中检索数据会很是快。若是没有索引,MongoDB必须扫描集合中的每个文档,这种扫描的效率很是低,尤为是在数据量较大时。数据库
下面以关系型数据库Oracle为例,介绍索引的基本原理,以下图所示:数组
从上图能够当作,索引的本质其实就至关因而一本书的目录。当查询表中数据的时候,先查询目录(索引)中的行地址,再经过行地址查询到表中的数据,从而提升查询的性能。数据结构
下图说明了在MongoDB中,索引在查询和排序中是如何工做的?性能
经过这个例子,能够清楚的看到索引存储的是一个特定字段或者几个字段的集合,而且按照必定的规律排序。当建立集合的时候,MongoDB自动在_id上建立一个惟一性索引,因为是惟一性的,因此能够防止重复的_id值插入到集合中。经过getIndexes能够查询到MongoDB集合上的索引信息,以下图所示。3d
当没有索引的时候,经过查看执行计划,能够看到查询的过程,以下:查询:10号部门,工资小于3000的文档。code
那么如何建立一个简单的索引呢?注意从mongoDB 3.0开始ensureIndex被废弃,从此都仅仅是db.collection.createIndex的一个别名。blog
如今在deptno和sal上创建一个索引,并从新查看执行计划:db.emp.createIndex({"deptno":1,"sal":-1})排序
注意:除了可使用explain()生成执行计划外,还能够有几个可选的参数,以下:
.explain("allPlansExecution")
.explain("executionStats")
.explain("queryPlanner")索引
单键索引是最普通的索引,与_id索引不一样,单键索引不会自动建立。ip
准备数据: 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做为一个总体。
多键索引与单键索引建立形式相同,区别在于字段的值。值具备多个记录,如数组。
如上图,基于集合上的数组建立多键索引,且数组为内嵌文档。
准备数据: 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()