索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。索引通常能极大的提高查询的效率。例如userInfo
集合里,有4个文档(省去了_id
字段)。如果现在需要查询所有年龄为18岁的人,db.userInfo.find({age:18})
会遍历所有文档,然后根据每个文档的位置信息,读出文档。当集合中的文档数量达到百万、千万或更多的情况下,对集合进行全表扫描,那开销将会非常大。
{
"name":"xiaoming",
"age":18,
"height":178
}
{
"name":"xiaohua",
"age":17,
"height":168
}
{
"name":"xiaomi",
"age":16,
"height":167
}
{
"name":"xiaobu",
"age":18,
"height":187
}
为了提高查找效率,可以对userInfo
集合的age
字段建立索引。建立索引后,MongoDB会额外存储一份按age
字段升序排序的索引数据,索引结构类似如下:
age | 位置信息 |
16 | 位置3 |
17 | 位置2 |
18 | 位置1 |
18 | 位置4 |
这样就可以快速的从索引里找出某个age值对应的位置信息,然后根据位置信息,读取对应的文档。那么如何添加索引呢?其实mongoDB在默认情况下就会为文档的_id
字段添加索引。其他字段的索引添加需要手动来操作,具体如下。
创建索引
db.collection.ensureIndex(keys, options)
方法在索引不存在的情况下,会在指定字段上创建索引。从3.0.0版本开始不推荐使用,现在用的另外一个名字:db.collection.createIndex()
。例如:
>db.userInfo.createIndex({"age":1})
上面脚本中,为表userInfo
的age
字段,指定按升序创建索引,如果想降序来创建,只需将字段的值改为"-1"即可。这种索引叫单字段索引(single field index)
。
该方法也可同时为多个字段创建索引,这种索引也叫复合索引
。首先按第一个字段排序,第一个字段相同的文档按第二个字段排序,依次类推。例如:
>db.userInfo.createIndex({"age":1,"height":1})
当索引的字段为数组时,创建出的索引称为多key索引
,多key索引会为数组的每个元素建立一条索引,比如userInfo
集合中加入一个字段skills
(数组)用于描述擅长技能。
{
"name":"xiaoming",
"age":18,
"height":178,
"skills":["painting","sing"]
}
需要查询相同技能的人就可以利用skills字段的多key索引。
>db.userInfo.createIndex({"skills":1}) //自动创建多key索引
注意: 虽然索引可以提供查询的效率,但是同时也降低了insert和update的效率。因为insert和update操作可能会重建索引,所以索引数不宜过多,一个表的索引数最好不要超过6个。
索引一般用在返回结果只是总体数据的一小部分的时候。根据经验,一旦返回的数据达到集合的一半时,就不要使用索引了。
若是已经对某个字段建立了索引,又想在大规模查询时不使用它(因为使用索引可能会低效),可以使用自然排序(指按照磁盘上的存储顺序返回数据),用{"$natural":1}
来强制mongodb禁用索引。如果某个查询不用索引,mongodb就会做全表扫描,即逐个扫描文档,遍历整个集合以找到结果。
参考文章