MongoDB复合索引命中hint后仍存在内存排序问题咨询
MongoDB复合索引未避免显式排序的原因说明
你执行的查询与使用的索引代码如下:
var exp = db.restaurants.explain("executionStats") // 给定的hint参数为 {"address.state": 1, "stars": 1, "name": 1} exp.find({ "address.state": "NY", stars: { $gt: 3, $lt: 4 } }).sort({ name: 1 }).hint(REDACTED)
出现显式SORT阶段的核心原因是:排序字段前的索引前缀存在范围查询,无法复用索引的有序性。
MongoDB复合索引的排序复用规则是:只有当索引定义中排在排序字段之前的所有字段,在查询中全部使用等值匹配时,排序字段的索引值才是全局有序的,才可以跳过内存排序步骤。你当前的场景不符合这个规则:
- 索引中排在排序字段
name之前的stars字段,查询时使用的是$gt/$lt范围匹配,不是等值匹配 - 对于相同的
address.state值,所有符合stars范围条件的索引条目,name字段的值不是按升序连续排列的,MongoDB无法直接按索引顺序返回符合排序要求的结果,因此必须触发显式SORT阶段完成排序。
如果需要避免内存排序,可以调整复合索引的顺序,将范围查询字段放在排序字段之后,调整后的索引为:{"address.state": 1, "name": 1, "stars": 1}。此时address.state为等值匹配,后续的name字段在索引中是连续有序的,可以直接复用索引顺序返回排序后的结果,再过滤符合stars范围条件的条目即可。
内容的提问来源于stack exchange,提问作者Vijay
相关产品推荐
相关产品推荐

