当索引包含查询扫描的所有字段时,该索引就涵盖了该查询。 覆盖查询会扫描索引而不是集合,从而提高查询性能。
如果对所查询字段的子集建立了索引,则索引还可以部分支持查询。
关于此任务
单个集合最多可以有64个索引。 但是,在达到该限制之前,过多的索引可能会降低性能。 对于写入读取比较高的集合,索引可能会降低性能,因为每次插入还必须更新任何索引。
步骤
识别常见查询
要识别应用程序中的常见查询模式,请使用 $queryStats聚合阶段。 $queryStats报告查询结构的指标,该结构根据共享字段对查询进行群组。
创建索引以支持常见查询
了解应用程序经常查询哪些字段后,就可以创建索引来支持对这些字段的查询。 有关更多信息,请参阅示例。
分析索引使用情况
应用程序开始使用索引后,您可以分析索引的有效性。 要查看索引统计信息和使用情况,您可以:
使用
$indexStats聚合阶段。对于MongoDB Atlas部署,请在Atlas 用户界面中查看索引。
请考虑删除未使用的索引以提高应用程序性能。 有关更多信息,请参阅删除不必要的索引。
定期重复此过程,确保索引支持当前工作负载。
示例
本页上的示例使用sample_mflix示例数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载示例数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。
注意
movies集合中的document包含此处未显示的其他字段。
创建单键索引
如果应用程序仅查询给定集合中的单个键,则需要为该集合创建单键索引。 示例,您可以在movies集合中的title上创建索引:
db.movies.createIndex( { title: 1 } )
此索引支持此查询:
db.movies.find( { title: 'Mulholland Drive' } )
创建复合索引
如果您的应用程序同时对单个键和多个键执行查询,则复合索引比单键索引更高效。 示例,您可以在year 、 runtime和title字段上创建索引:
db.movies.createIndex( { year: 1, runtime: 1, title: 1 } )
索引前缀
复合索引支持对索引前缀进行查询,索引前缀是索引字段的起始子集。示例,前面的索引支持此查询:
db.movies.find( { year: 2012, runtime: { $gt: Decimal128( "120" ) } }, { title: 1 } )
有关索引前缀的更多信息和性能注意事项,请参阅索引前缀。
创建索引以支持 $text 查询
对于MongoDB上托管的数据,您可以使用MongoDB搜索索引支持全文搜索。要学习;了解更多信息,请参阅创建MongoDB搜索索引。
对于自托管(非 Atlas)部署, MongoDB提供了 text索引类型,支持在集合中搜索string内容。 要学习;了解有关自管理文本索引的更多信息,请参阅自管理部署上的文本索引。
创建向量搜索索引
向量搜索索引支持对向量嵌入进行查询。 要创建向量搜索索引,请参阅向量搜索的索引字段。
索引使用和排序规则
要使用索引进行 string 比较,操作还必须指定相同的排序规则。如果操作指定的排序规则与索引指定的排序规则不同,则索引不支持对索引字段进行 string 比较。
警告
对于不带排序规则的索引,支持排序规则的索引键可能大于索引键,因为配置排序规则的索引使用 ICU 排序规则键来实现排序顺序。
使用以下代码在 sample_mflix数据库的 movies集合上创建索引,排序规则区域设置设置为 "fr",用于 string 比较:
db.movies.createIndex( { title: 1 }, { collation: { locale: "fr" } } )
以下查询指定与索引相同的排序规则,可以使用该索引:
db.movies.find( { title: "Les Misèrables" }, { title: 1, year: 1 } ).collation( { locale: "fr" } )
但是,以下查询操作默认使用“简单” binary 排序器,无法使用索引且需要 COLLSCAN。
db.movies.find( { title: "Les Misèrables" }, { title: 1 , year: 1 } )
如果一个复合索引的前缀键不是字符串、数组和嵌入式文档,在这种情况下,即使查询操作指定了一个与索引不同的排序规则,它仍然可以利用该复合索引来支持对其前缀健的比较。
示例,您可以使用以下代码在 sample_mflix数据库的 movies集合上创建复合索引,指定数字字段 year 和 metacritic 以及字符串字段title。该索引还指定了用于字符串比较的排序规则区域设置"fr":
db.movies.createIndex( { year: 1, metacritic: 1, title: 1 }, { collation: { locale: "fr" } } )
以下操作使用 "simple" 二进制排序规则进行字符串比较,它们可以使用索引:
db.movies.find( { year: 2012 }, { title: 1, year: 1, metacritic: 1 } ).sort( { title: 1 } )
db.movies.find( { year: 2012, metacritic: { $gt: Decimal128( "50" ) } }, { title: 1, year: 1, metacritic: 1 } ).sort( { title: 1 } )
以下操作使用 "simple" 二进制排序规则对索引的 title 字段进行字符串比较,它们可以使用索引仅完成查询的 year: 2012 部分:
db.movies.find( { year: 2012, title: "Les Misèrables" }, { year: 1, title: 1 } )
要确认查询是否使用了索引,请使用 explain() 选项运行查询。
重要
针对文档键(包括嵌入式文档键)的匹配使用简单的二进制比较。这意味着对“type.café”等键的查询将与键“type.cafe”不匹配,无论您为强度参数设立的值如何。