文档菜单
文档首页
/
MongoDB 手册
/ /

ESR(等价性、排序、范围)规则

本页内容

  • 等价性
  • 排序
  • 范围
  • 其他考虑因素
  • 示例
  • 了解更多

引用多个字段的索引是组合索引。组合索引可以显著提高查询响应时间。

索引键对应于文档字段。在大多数情况下,将 ESR(等价性、排序、范围)规则应用于索引键的排列可以帮助创建更高效的 组合索引

本页面介绍了ESR规则。有关查询优化的更多信息,请参阅explain查询计划。

提示

要在测试索引时强制MongoDB使用特定的索引,请使用cursor.hint()

“相等性”指的是对单个值的精确匹配。以下精确匹配查询扫描cars集合,查找其model字段与Cordoba完全匹配的文档。

db.cars.find( { model: "Cordoba" } )
db.cars.find( { model: { $eq: "Cordoba" } } )

索引搜索通过有效地使用精确匹配来限制需要检查的文档数量。请将需要精确匹配的字段放在索引的第一位。

索引可能具有多个键,用于具有精确匹配的查询。相等匹配的索引键可以以任何顺序出现。然而,为了满足索引的相等匹配,所有精确匹配的索引键都必须在其他索引字段之前。MongoDB的搜索算法消除了对精确匹配字段进行特定顺序排列的需要。

精确匹配应该是选择性的。为了减少扫描的索引键数量,请确保相等测试至少消除90%的可能文档匹配。

“排序”确定结果顺序。排序遵循相等匹配,因为相等匹配减少了需要排序的文档数量。在相等匹配之后进行排序也允许MongoDB进行非阻塞排序。

索引可以在查询字段是索引键的子集时支持排序操作。只有当查询包含所有前缀键(在排序键之前)的相等条件时,才支持对索引键子集的排序操作。有关更多信息,请参阅索引的排序和非前缀子集。

以下示例查询了cars集合。输出结果按照model进行排序。

db.cars.find( { manufacturer: "GM" } ).sort( { model: 1 } )

为了提高查询性能,请在manufacturermodel字段上创建索引。

db.cars.createIndex( { manufacturer: 1, model: 1 } )
  • manufacturer是第一个键,因为它是一个相等匹配。

  • model的索引顺序(1)与查询顺序相同。

"范围"过滤器扫描字段。扫描不需要精确匹配,这意味着范围过滤器与索引键松散关联。为了提高查询效率,请限制范围边界并使用相等匹配来减少扫描的文档数。

范围过滤器类似于以下内容

db.cars.find( { price: { $gte: 15000} } )
db.cars.find( { age: { $lt: 10 } } )
db.cars.find( { priorAccidents: { $ne: null } } )

MongoDB无法对范围过滤器的结果执行索引排序。将范围过滤器放置在排序谓词之后,以便MongoDB可以使用非阻塞索引排序。有关阻塞排序的更多信息,请参阅cursor.allowDiskUse()

  • 不等式运算符,如$ne$nin,是范围运算符,而不是相等运算符。

  • $regex是范围运算符。

  • $in:

    • 当单独使用 $in 时,它是一个等于操作符,执行一系列的相等匹配。

    • 当使用 $in.sort()

      • 如果 $in 有少于 200 个数组元素,元素会被展开并按照索引指定的排序方式合并。这提高了小数组的性能。$in 类似于带有 ESR 的等价谓词。

      • 如果 $in 有 200 个或更多的元素,元素会被像范围操作符一样排序。在这种情况下,小数组的性能提升没有实现。索引的后续字段无法提供排序,并且 $in 类似于带有 ESR 的范围谓词。

      • 如果您通常使用小数组与 $ins,请在索引规范中将 $ins 放得更早。如果您通常使用大数组,请在包含范围谓词的位置包含 $ins

注意

200 的限制可能会更改,并且不能保证在所有 MongoDB 版本中保持不变。

以下查询搜索 cars 集合中由福特制造的、价格超过 15,000 美元的车辆。结果按型号排序

db.cars.find(
{
manufacturer: 'Ford',
cost: { $gt: 15000 }
} ).sort( { model: 1 } )

查询包含 ESR 规则的所有元素

  • manufacturer: 'Ford' 是基于等价的匹配

  • cost: { $gt: 15000 } 是基于范围匹配,并且

  • model 用于排序

根据 ESR 规则,示例查询的最佳索引是

{ manufacturer: 1, model: 1, cost: 1 }

返回

策略