MST

星途 面试题库

面试题:MongoDB专享索引在复杂查询中的优化策略

假设在一个包含大量用户数据的MongoDB集合中,用户数据包括基本信息、订单记录等,现在需要执行一个复杂查询,涉及多个字段的条件过滤和排序。请详细说明如何通过专享索引来优化这个查询,包括如何选择字段创建专享索引以及创建索引的顺序等方面。
41.3万 热度难度
数据库MongoDB

知识考点

AI 面试

面试题答案

一键面试
  1. 选择字段创建专享索引
    • 条件过滤字段
      • 对于在 $match 阶段使用的字段,优先创建索引。例如,如果查询条件是 {"basicInfo.age": {"$gte": 18}, "orderRecord.totalAmount": {"$gt": 100}},那么 basicInfo.ageorderRecord.totalAmount 字段应该考虑创建索引。因为这些字段用于过滤大量数据,索引可以帮助快速定位符合条件的文档。
      • 如果有多个条件是 $and 关系,创建复合索引会更有效。例如 {"basicInfo.gender": "male", "basicInfo.age": {"$gte": 30}},可以创建一个包含 basicInfo.genderbasicInfo.age 的复合索引。
    • 排序字段
      • 如果查询中有 $sort 操作,对排序字段创建索引能提升性能。例如 {"$sort": {"orderRecord.orderDate": -1}},则需要对 orderRecord.orderDate 创建索引。如果同时有过滤和排序操作,并且过滤字段和排序字段有重叠部分,可以考虑将这些字段组合成复合索引,以满足两种操作的性能优化需求。
  2. 创建索引的顺序
    • 复合索引顺序
      • 在复合索引中,字段顺序非常关键。一般将选择性高的字段(即该字段值的唯一性较高,能快速缩小查询范围)放在前面。例如对于复合索引涉及 basicInfo.countrybasicInfo.city,如果 country 不同值的数量相对 city 较少(即 country 选择性低),而 city 选择性高,那么复合索引应该是 {basicInfo.city: 1, basicInfo.country: 1}(假设升序排序)。这样在查询时,先根据 city 快速缩小范围,再根据 country 进一步过滤。
      • 如果既有过滤条件又有排序条件,将过滤条件中选择性高的字段放在复合索引前面,然后是排序字段。例如查询 {"basicInfo.occupation": "engineer", "$sort": {"orderRecord.orderAmount": -1}},复合索引可以是 {basicInfo.occupation: 1, orderRecord.orderAmount: -1}
  3. 创建索引示例: 在 MongoDB 中,可以使用以下命令创建索引:
// 创建单字段索引
db.users.createIndex({"basicInfo.age": 1});
// 创建复合索引
db.users.createIndex({"basicInfo.gender": 1, "basicInfo.age": 1});

在实际应用中,要通过 explain 命令来验证索引是否生效以及查询性能是否得到优化。例如:

db.users.aggregate([
    {"$match": {"basicInfo.age": {"$gte": 18}, "orderRecord.totalAmount": {"$gt": 100}}},
    {"$sort": {"orderRecord.orderDate": -1}}
]).explain("executionStats");

通过分析 explain 的结果,可以进一步调整索引策略,确保查询性能最优。