一、简介
在MongoDB建立索引能提高查询效率,如果没有建立索引,在查询时,MongoDB必须执行全表扫描,在数据量大时,效率差别就很明显,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。
- 索引是特殊的数据结构,
- 索引存储在一个易于遍历读取的数据集合中,
- 索引是对数据库表中一列或多列的值进行排序的一种结构。
- 索引项的排序支持高效的相等匹配和基于范围的查询操作。
注意:从mongoDB 3.0开始ensureIndex被废弃,使用 createIndex创建索引。
创建索引的语法:
db.collection.createIndex(keys,options)
参数 | 类型 | 描述 |
---|---|---|
keys | document | 一个包含该字段的字段和值对的文档,该文档的索引键和该值描述该字段的索引类型。对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为1。MongoDB支持几种不同的索引类型,包括文本,空间,和哈希索引。查看更多信息的索引类型。右 |
options | document | 在创建索引的时的限制条件 |
二、 索引的基本操作
我们先插入10w条记录
let arr = [];
for(let i=1; i<=1000000; i++){//15s
arr.push({
"number" : i,
"date" : "2015-07-02",
"cname" : "zcy"+i,
"items" :[ {
"ino" : i,
"quantity" : i,
"price" : 4.0
},{
"ino" : i+1,
"quantity" : i+1,
"price" : 6.0
}
]
})
}
db.orders.insert(arr)
1. 默认索引
存储在MongoDB集合中的每个文档(document)都有一个默认的主键“_id“,如果我们在添加新的文档时,没有指定“_id“值时,MongoDB会创建一个ObjectId值,并会自动创建一个索引在“_id“键上,默认索引的名称是”id“,并无法删除,如下面的命令查看:
db.orders.getIndexes()
返回一个数组,该数组保存标识和描述集合上现有索引的文档列表,可以查看我们是否有对某个集合创建索引,并创建哪些索引,方便我们管理。
2. 创建单列索引
我们对文档单个字段创建索引或者对内嵌文档的单个字段创建索引
语法:
db.collection.createIndex({field:boolean} })
boolean:对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为-1。
(1)创建
db.orders.createIndex({cname:1})
我们对orders集合创建了cname索引,默认的索引名称是”cname_1“
(2)根据条件查询文档,并查看查询效率怎么样
db.orders.find({“cname”:“zcy100000”}).explain()
explain():查看查询信息,包含是否走索引
1):没建索引时,查询条件cname为zcy100000的文档
2)有建索引,查询条件cname为zcy100000的文档
我们结果是相差很大的,有建索引字段,查询效率比较高,在大数据时,差别更明显。
(3). 创建组合索引
我们可以同时对多个键创建组合索引
db.orders.createIndex({cname:1,number:-1})
(1)我们对cname和number作为查询条件时
db.orders.find({“cname”:{$gt:“zcy1000”},“number”:2000}).explain()
2)我们只用两个索引其中一个作为查询时
第一种情况:我们条件只使用"cname":{$gt:“zcy1000”}作为查询条件
db.orders.find({"cname":{$gt:"zcy1000"}}).explain()
第二种情况:我们条件只使用"number":2000作为查询条件
总结:我们在使用组合索引时,查询时会用到组合索引的前端的几种组合。
我们对a、b进组合创建索引,支持查询时会用到索引的几种:
- a
- a,b
4. 内嵌文档的索引
我们对内嵌文档创建索引时,跟基本文档创建索引一样
db.collection.createIndex({field:boolean} })
(1):单列的内嵌文档的索引创建
db.orders.createIndex({"items.info":1})
我们以items.info字段作为查询条件,并使用索引的情况
db.orders.find({"items.info":{$lt:100}}).explain()
(2):组合的内嵌文档的索引的创建
我们对内嵌文档创建组合索引时,跟基本文档创建组合索引一样
db.orders.createIndex({"items.info":1, "items. quantity":-1})
5. 删除索引
我们对已经创建的索引进行删除,可以针对具体的集合中索引进行删除,也可以对所有的集合中的所有索引删除
(1)具体索引名称删除索引
删除具体的索引,根据索引名称删除,如果不知道索引的名称,可以通过db.collection.getIndexes()查看索引名称
db.orders.dropIndex(“cname_1”)
(2)删除集合中所有索引谨慎使用
db.orders.dropIndexes()
总结:
在MongoDB建立索引能提高查询效率,但在MongoDB新增、修改效率上比较慢