普通索引

普通索引根据创建时所关联字段的数量,分为单字段索引和复合索引。单字段索引是指仅根据记录中某一字段创建的索引,多字段索引是指结合记录中多个字段创建的索引。如果用户在查询时经常使用某几个字段,可以为这些字段创建复合索引,会比任意一个单字段索引的查询速度更快,使准确查询更加高效。

单字段索引

以单个字段创建索引

集合 sample.employee 中存在如下记录:

{"id": 1, "name": "Mark", "score": 432, "info": {"age": 18, "city": "Shanghai"}}
{"id": 2, "name": "Adam", "score": 475, "info": {"age": 32, "city": "Beijing"}}
{"id": 3, "name": "Sam", "score": 494, "info": {"age": 28, "city": "Guangzhou"}}
{"id": 4, "name": "Jenny", "score": 483, "info": {"age": 23, "city": "Guangzhou"}}

以集合的 score 字段创建倒序索引,索引名为“scoreIdx”

> db.sample.employee.createIndex("scoreIdx", {"score": -1})

Note:

创建索引的详细参数说明可参考 createIndex()

查看条件为{"score": 28}的查询所对应的访问计划

> db.sample.employee.find({"score": 28}).explain()

输出信息中显示该查询已使用索引 scoreIdx

{
  ···
  "Role": "data",
  "Name": "sample.employee",
  "ScanType": "ixscan",
  "IndexName": "scoreIdx",
  ···
}

以对象字段创建索引

用户可以在集合中以对象字段创建索引,以快速查找对象字段中的数据。

集合 sample.employee 中存在如下记录:

{"id": 1, "name": "Mark", "score": 432, "info": {"age": 18, "city": "Shanghai"}}
{"id": 2, "name": "Adam", "score": 475, "info": {"age": 32, "city": "Beijing"}}
{"id": 3, "name": "Sam", "score": 494, "info": {"age": 28, "city": "Guangzhou"}}
{"id": 4, "name": "Jenny", "score": 483, "info": {"age": 23, "city": "Guangzhou"}}

以集合的 info 字段创建升序索引,索引名为“infoIdx”

> db.sample.employee.createIndex("infoIdx", {"info": 1})

查看条件为{"info": {"age": 32, "city": "Beijing"}}的查询所对应的访问计划

> db.sample.employee.find({"info": {"age": 32, "city": "Beijing"}}).explain()

输出信息中显示该查询已使用索引 infoIdx

{
  ···
  "Role": "data",
  "Name": "sample.employee",
  "ScanType": "ixscan",
  "IndexName": "infoIdx",
  ···
}

以对象嵌套字段创建索引

用户可以在集合中以对象嵌套字段创建索引,以实现更精准的查询。

集合 sample.employee 中存在如下记录:

{"id": 1, "name": "Mark", "score": 432, "info": {"age": 18, "city": "Shanghai"}}
{"id": 2, "name": "Adam", "score": 475, "info": {"age": 32, "city": "Beijing"}}
{"id": 3, "name": "Sam", "score": 494, "info": {"age": 28, "city": "Guangzhou"}}
{"id": 4, "name": "Jenny", "score": 483, "info": {"age": 23, "city": "Guangzhou"}}

以集合的 info.age 字段创建升序索引,索引名为“ageIdx”

> db.sample.employee.createIndex("ageIdx", {"info.age": 1})

查看条件为{"info.age": {$et: 28}}的查询所对应的访问计划

> db.sample.employee.find({"info.age": {$et: 28}}).explain()

输出信息中显示该查询已使用索引 ageIdx

{
  ···
  "Role": "data",
  "Name": "sample.employee",
  "ScanType": "ixscan",
  "IndexName": "ageIdx",
  ···
}

复合索引

使用

集合 sample.employee 中存在如下记录:

{"area_id": 1, "name": "Mark", "score": 432, "info": {"age": 18, "city": "Shanghai"}}
{"area_id": 1, "name": "Adam", "score": 475, "info": {"age": 32, "city": "Shanghai"}}
{"area_id": 2, "name": "Sam", "score": 494, "info": {"age": 28, "city": "Guangzhou"}}
{"area_id": 2, "name": "Jenny", "score": 483, "info": {"age": 23, "city": "Guangzhou"}}

以集合的 name 和 info 字段创建正序索引,索引名为“sortIdx”

> db.sample.employee.createIndex("sortIdx", {"name": 1, "info": 1})

Note:

创建索引的详细参数说明可参考 createIndex()

查看条件为{name: "Sam", "info.age": 28}的查询所对应的访问计划

> db.sample.employee.find({name: "Sam", "info.age": 28}).explain()

输出信息中显示该查询已使用索引 sortIdx

{
  ···
  "Role": "data",
  "Name": "sample.employee",
  "ScanType": "ixscan",
  "IndexName": "sortIdx",
  ···
}

前缀

复合索引支持最左前缀原则,以实现索引的复用,减少数据库因维护索引而导致的资源消耗。例如,集合中存在索引 testIdx,字段定义如下:

> db.sample.employee.createIndex("testIdx", {"x": 1, "y": 1, "z": 1})

那么该索引具有以下前缀:

{"x": 1}
{"x": 1, "y": 1}

因此以下查询均可以使用该索引:

> db.sample.employee.find({"x": 10, "y": 10, "z": 100})
> db.sample.employee.find({"x": 10, "y": 10})
> db.sample.employee.find({"x": 10, "z": 10})
> db.sample.employee.find({"x": 10})

而类似 {"y": 10}{"y": 10, "z": 100} 的查询条件则无法使用该索引。

参考

更多操作可参考

操作 说明
query.explain() 获取查询的访问计划
SdbCollection.dropIndex() 删除指定索引
回到顶部