本章内容:
- 若所有查询都使用同一单键,则创建单键索引
- 创建复合索引以,支持多种查询
- 索引的使用和排序
当索引包含该查询扫描的所有字段时,该索引就支持该查询。该查询将扫描的事索引而非集合。创建支持查询的索引可以大大提高查询性能。
本文介绍了用于创建支持查询的索引的策略。
一、若所有查询都是单键查询,则创建单键索引
如果只查询给定集合中的单个键,则只需要为该集合创建一个单键索引。例如,在product集合的category 字段上创建索引:
db.products.createIndex( { "category": 1 } )
二、创建复合索引,支持多种查询
如果有时只查询一个键,而有时又查询该键和另一个键的组合,那么创建复合索引比创建单键索引更有效。
MongoDB将对两个查询使用复合索引。例如,同时在category 和 item字段上创建索引。
db.products.createIndex( { "category": 1, "item": 1 } )
可以仅查询category ,也可以查询category 与 item的组合。多个字段上的单个复合索引可以支持所有搜索这些字段的“前缀”子集的查询。
例子
集合上的如下索引:
{ x: 1, y: 1, z: 1 }
可支持以下索引查询:
{x:1}
{x:1,y:1}
在某些情况下,前缀索引可能会提供更好的查询性能:例如,如果z是一个大数组。
{x:1,y:1,z:1}索引还可以支持类似索引{x:1,z:1}这样相同的查询。
另外,{x:1,z:1}还有其他用途。如下查询:
db.collection.find({x:5}).sort({z:1})
{x:1,z:1}索引支持查询和排序操作,而{x:1,y:1,z:1}索引仅支持查询。
有关排序的更多信息,请参见使用索引对查询结果进行排序。
从2.6版开始,MongoDB可以使用索引交集来完成查询。创建支持查询的复合索引还是依赖索引交集之间的选择取决于系统的具体情况。有关更多详细信息,请参见索引交集和复合索引。
三、索引使用和排序
要将索引用于字符串比较操作,该操作还必须指定相同的排序规则(collation)。即,如果该操作指定了不同的排序规则,则具有排序规则的索引不能支持对索引字段进行字符串比较的操作。
说明
Collation特性允许MongoDB根据不同的语言定制排序规则,举个例子,一个存储中国用户信息的集合。例如比如name字段存储汉字。默认情况下,name字段会被当做一个普通的二机制字符串来进行比较操作。如果name按拼音顺序排序的话,可以通过collation来设置:{collation: {locale: "zh"}}。
例如,在集合myColl的字符串类型字段 category上创建索引,同时设置索引排序语言(collation locale)设置为“ fr”。
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )
以下查询操作指定与索引相同的排序规则,可以使用索引:
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )
但是,下面的查询操作则无法使用索引(默认情况下使用“ simple”二进制排序):
db.myColl.find( { category: "cafe" } )
对于索引前缀键不是字符串,数组和嵌入式文档的复合索引,指定不同排序规则的操作仍可以使用索引来支持索引前缀键的比较。
例如,在集合myColl的数字类型字段score和price以及字符串类型字段 category上创建复合索引;同时指定排序规则语言为“ fr”创建索引,来进行字符串比较:
db.myColl.createIndex(
{ score: 1, price: 1, category: 1 },
{ collation: { locale: "fr" } } )
下面操作使用“simple”二进制排序规则进行字符串比较,该操作可以使用索引:
db.myColl.find( { score: 5 } ).sort( { price: 1 } )
db.myColl.find( { score: 5, price: { $gt: NumberDecimal( "10" ) } } ).sort( { price: 1 } )
如下操作将“simple”二进制排序规则用于索引 category字段上的字符串比较,该操作可以使用索引仅满足score: 5 部分:
db.myColl.find( { score: 5, category: "cafe" } )