创建索引以支持查询
当索引包含查询扫描的所有字段时,它就支持该查询。该查询扫描的将会是索引而不是集合。创建支持查询的索引可大幅提高查询性能。
本文档介绍了创建支持查询的索引的各种策略。
如果所有查询均使用同一单键,则创建单键索引
如果只查询某集合中的一个键,则只需为该集合创建一个单键索引。例如,您可对 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 可以使用索引交集来完成查询。 选择创建支持查询的复合索引还是依赖索引交集取决于系统的具体情况。 有关更多详细信息,请参阅索引交集和复合索引。
创建索引以支持文本搜索
对于托管在 MongoDB Atlas 上的数据,您可以通过 Atlas Search 索引来支持全文搜索。要了解更多信息,请参阅 创建 Atlas Search 索引。
对于自托管(非 Atlas)部署, MongoDB提供了 text
索引类型,支持在集合中搜索string内容。 要学习;了解有关自管理文本索引的更多信息,请参阅自管理部署上的文本索引。
索引使用和排序规则
要使用索引进行字符串比较,操作还必须指定相同的排序规则。换言之,如果一个操作对索引字段进行字符串比较,但又设定了与索引字段不同的排序规则,那么这个设有排序规则的索引将无法支持该操作。
警告
由于配置了排序规则的索引是通过 ICU 排序规则键来实现排序,因此,相比未配置排序规则的索引的索引键,有排序规则感知的索引键可能会更大。
例如,集合 myColl
在字符串字段 category
上具有一个索引,排序规则语言环境为 "fr"
。
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )
以下查询操作指定了与索引相同的排序规则,因此可以使用索引:
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )
而以下查询操作默认使用“简易的”二进制排序器,因此无法使用索引:
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" } )
重要
与文档键(包括嵌入式文档键)的匹配使用简单的二进制比较。这意味着类似“foo.bár”的键的查询不会匹配“foo.bar”键,无论您为 strength 参数设置了什么值。