Docs 菜单
Docs 主页
/
数据库手册
/ /

ESR(相等、排序、范围)指南

引用多个字段的索引是复合索引。复合索引可大幅缩短查询响应时间。

索引键对应于文档字段。在大多数情况下,应用 ESR(相等、排序、范围)准则来排列索引键有助于创建更高效的复合索引。

确保相等字段始终排在第一位。将相等性应用于复合索引的前导字段,可让您利用其余字段值按排序顺序排列的优势。接下来,根据索引的特定需求,选择使用排序字段还是范围字段:

  • 如果避免内存中排序很重要,请将排序字段放在范围字段之前 (ESR)

  • 如果查询中的范围谓词具有很强的选择性,请将其放在排序字段 (ERS) 之前

本页介绍了 ESR 指南。有关优化查询的详细信息,请参阅 explain查询计划

提示

要强制MongoDB使用特定索引,请在测试索引时使用游标.hint()(mongosh方法)。

“相等”系指单个值的精确匹配。以下精确匹配查询扫描 cars 集合以查找 model 字段 Cordoba 精确匹配的文档。

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

索引搜索可有效利用精确匹配来减少检查的索引键数量。相等字段必须放在第一位。当您使用索引的第一部分来确保相等时,索引的其余部分将保持排序顺序。

一个索引可能有多个用于精确匹配的键。用于等值匹配的索引键可以以任何顺序出现。但是,如要使用索引满足等值匹配,所有用于精确匹配的索引键必须放在其他索引字段之前。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 } } )

如果查询中的范围谓词选择性很强,请将其放在排序字段之前,以减少已排序文档的数量并允许进行内存中排序。

要避免内存中排序,请将范围过滤放在排序谓词之后。有关内存中排序的更多信息,请参阅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 }

后退

Strategies

在此页面上