- Published on
Mongodb Index 优化实践
- Authors
- Name
- Shelton Ma
1. Mongodb 索引优化过程
1. 复合索引顺序优化: 如何尽可能命中更多索引
首先创建一些组合索引/单列索引, 然后执行
explain()
在
queryPlanner
中查看winningPlan
是否符合预期, 如果在stage: 'IXSCAN',
indexName:
没有使用预期的索引, 说明说明不符合最优查询, 可以根据索引中各字段的分布规律/字段类型等特征排序如果选择了一些更短的索引, 而不是选择命中最多的索引, 可以尝试将最多索引按照最短索引的顺序重新生成
如果mongodb发生索引误判, 可以强制执行来对比查询效果, 但不建议长期使用
db.SecurityAlert.find({ attackStatus: 1, organization: "ABC" }) .hint({ attackStatus: 1, organization: 1 }) .explain("executionStats")
lte, $in) 可能直接选择全表扫描
2. 查询优化器对大范围查询 (3. 使用索引覆盖 (Covered Query), 确保索引包含查询字段和返回字段,避免回表 (fetch)
2. 背景介绍
Query Planner 选择最优索引,而非最多索引
MongoDB 的查询优化器 不会选取命中最多索引的查询计划,而是根据 查询代价 (Cost-Based Optimization, CBO) 选择执行效率最高的索引。即使某个查询命中了多个索引,它也可能只选用一个最优索引,甚至排除所有命中的索引,原因如下
- 索引扫描成本:查询优化器计算索引扫描的扫描键数 (keysExamined) 和 返回文档数 (docsExamined),如果某个索引的扫描代价更低,即使它命中字段更少,MongoDB 也可能优先选择它。
- 索引覆盖率:如果某个索引可以 覆盖查询 (covered query),MongoDB 更倾向于使用它,而不是命中多个索引但仍需回表 (fetch documents) 的情况。
- 查询的选择性 (Selectivity):
- 高选择性:如果索引能大幅减少查询结果集(如
{ field: 1 }
索引在 field=5 仅返回 1% 的数据),则 MongoDB 更倾向于使用它。 - 低选择性:如果索引返回的数据量太大(如
field: { $gt: 1 }
返回 90% 数据),MongoDB 可能会选择全表扫描 (COLLSCAN) 而排除所有索引。
- 高选择性:如果索引能大幅减少查询结果集(如