创建索引以支持查询
当索引包含查询扫描的所有字段时,该索引就涵盖了该查询。 覆盖查询会扫描索引而不是集合,从而提高查询性能。
如果对所查询字段的子集建立了索引,则索引还可以部分支持查询。
关于此任务
单个集合最多可以有64个索引。 但是,在达到该限制之前,过多的索引可能会降低性能。 对于写入读取比较高的集合,索引可能会降低性能,因为每次插入还必须更新任何索引。
步骤
识别常见查询
要识别应用程序中的常见查询模式,请使用 $queryStats
聚合阶段。 $queryStats
报告查询结构的指标,该结构根据共享字段对查询进行群组。
创建索引以支持常见查询
了解应用程序经常查询哪些字段后,就可以创建索引来支持对这些字段的查询。 有关更多信息,请参阅示例。
分析索引使用情况
应用程序开始使用索引后,您可以分析索引的有效性。 要查看索引统计信息和使用情况,您可以:
使用
$indexStats
聚合阶段。对于MongoDB Atlas部署,请在Atlas 用户界面中查看索引。
请考虑删除未使用的索引以提高应用程序性能。 有关更多信息,请参阅删除不必要的索引。
定期重复此过程,确保索引支持当前工作负载。
示例
创建单键索引
如果应用程序仅查询给定集合中的单个键,则需要为该集合创建单键索引。 示例,您可以在product
集合中的category
上创建索引:
db.products.createIndex( { category: 1 } )
前面的索引支持此查询:
db.products.find( { category: "electronics" } )
创建复合索引
如果您的应用程序同时对单个键和多个键执行查询,则复合索引比单键索引更高效。 示例,您可以在category
、 item
和location
字段上创建索引:
db.products.createIndex( { category: 1, item: 1, location: 1 } )
索引前缀
复合索引支持对索引前缀进行查询,索引前缀是索引字段的起始子集。 示例,前面的索引支持以下查询:
db.products.find( { category: "electronics" } ) db.products.find( { category: "electronics", item: "television" } )
有关索引前缀的更多信息和性能注意事项,请参阅索引前缀。
创建索引以支持文本搜索
对于托管在 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 参数设置了什么值。