当存在多个索引时,mongodb 在执行查询时如何选择索引

问题描述 投票:0回答:1

我有一个 MongoDB 集合,用于存储一些测试提交。高级架构如下所示。

{
  "lessonType": "quiz",
  "userId": "639cb6d9513a420026eddca1"
  "courseId": "639cb6d9513a420026eddca2",
  "lessonId": "639cb6d9513a420026eddca3",
  ...some_more_fields

}

现在这个集合有两个索引。

第一个:

{ courseId: 1, lessonId: 1, userId:1 }

第二个:

{ lessonType: 1, courseId: 1 }

lessonType 只有两个值,分别是

quiz
assignment

现在我想查找特定课程的所有提交,其类型为

quiz

示例查询:

{ courseId: ObjectId("63a2eb428899436daf7eb489"),lessonType: "quiz" }

上面的查询始终考虑上面提到的第一个索引,而不是第二个索引。

在第一个索引中,只有

courseId
才有用,但在第二个索引中,它可以同时使用
courseId
lessonType

如果使用第二个索引,需要扫描的文档将减少2倍。

这里有什么建议吗?

我浏览了一些建议在执行查询时提供提示的文章。

还有其他办法吗?

如果第二个索引性能更高,为什么 mongo 默认不使用它?

database mongodb indexing mongodb-query query-optimization
1个回答
0
投票

在 MongoDB 中,查询规划器尝试通过考虑多种因素来为查询选择最有效的执行路径。

请注意,出于以下几个原因,查询计划器可能不会选择您认为最有效的索引:

  1. 选择性:如果“lessonType”没有选择性(即,它具有很少的唯一值,如您的情况),查询计划器可能会认为扫描此索引效率低下。
  2. 索引顺序:索引中键的顺序很重要。在第一个索引中,
    courseId
    是第一个键,而在第二个索引中,
    lessonType
    是第一个,这可能会影响选择。
  3. 底层算法和启发式:查询规划器根据复杂的算法和启发式做出决策,这并不总是符合我们人类的直觉。

至于你关于提示的问题,是的,提示是一种手动指示 Mongo 数据库引擎使用特定索引进行查询的方法,绕过查询规划器的自动选择过程。

但要小心,如果操作不当,使用提示强制使用特定索引可能会适得其反,由 MongoDB 规划者来决定可能会更有效。理想情况下,MongoDB 应该能够自动为您的查询选择最佳索引,但情况并非总是如此。

如果索引效率始终是一个问题,您可能需要考虑修改索引策略。也许像

{ courseId: 1, lessonId: 1 }
{ courseId: 1, lessonType: 1}
这样的索引更适合您的工作负载。请记住,每个索引决策都是存储空间、写入性能和读取性能之间的权衡。

这里是建议如何使用复合索引的官方文档

索引前缀是索引字段的开始子集。复合索引支持对索引前缀中包含的所有字段进行查询。 (https://www.mongodb.com/docs/manual/core/indexes/index-types/index-compound/#index-prefixes

© www.soinside.com 2019 - 2024. All rights reserved.