创建索引以支持查询
当索引包含查询扫描的所有字段时,它就支持该查询。该查询扫描的将会是索引而不是集合。创建支持查询的索引可大幅提高查询性能。
本文档介绍了创建支持查询的索引的各种策略。
如果所有查询均使用同一单键,则创建单键索引
如果只查询某集合中的一个键,则只需为该集合创建一个单键索引。例如,您可对 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 }
索引仅支持查询。有关排序的更多信息,请参阅使用索引对查询结果排序。
创建索引以支持文本搜索
对于托管在 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 参数设置了什么值。