MongoDB索引选择:优先减少总键检查数还是总文档检查数?
MongoDB索引选择的经验法则(基于查询性能对比)
查询性能对比数据
| Metric | Index 1 | Index 2 |
|---|---|---|
| nReturned | 1 898 | 1 898 |
| executionTimeMillis | 17 673 | 16 500 |
| totalKeysExamined | 2 639 327 | 8 306 686 |
| totalDocsExamined | 2 639 276 | 5 732 |
注:executionTimeMillis数据可能存在误导,不加explain时两个索引的查询耗时均约1秒。
索引选择的核心经验
1. 优先关注「文档扫描数(totalDocsExamined)」
磁盘读取文档的开销比内存扫描索引键大几个数量级。Index2仅扫描5732个文档,远低于Index1的260多万,这意味着它能精准定位目标文档,避免大量无意义的磁盘IO。哪怕Index2的索引键扫描数更高,内存操作的成本几乎可以忽略,长期运行中文档扫描少的索引性能稳定性会碾压前者。
2. 忽略explain的执行时间偏差
你提到实际查询耗时均为1秒,说明explain自身的统计计算放大了时间差,这个指标不具备决策价值。真正要参考的是生产环境真实请求的延迟,以及高并发下的负载表现。但扫描数的差异能直接预判扩展性:文档扫描多的索引,数据量增长后延迟必然飙升。
3. 评估索引的「过滤精准度」与「覆盖能力」
Index2文档扫描少,大概率是因为它的结构更贴合查询需求:
- 要么包含了查询的所有过滤字段,能快速缩小结果范围;
- 要么是覆盖索引——索引中包含了查询需要的所有字段,无需读取原文档就能返回结果。
你可以核对查询的过滤条件、投影字段是否都在Index2中,这是它性能优势的核心原因。
4. 优先选扩展性强的索引
Index1扫描的文档数是返回结果的1300多倍,过滤效率极低。当数据库数据量从几百万涨到几千万时,它的扫描数会成比例增长,磁盘IO会直接成为瓶颈。而Index2的扫描数仅为返回结果的3倍左右,过滤精准,数据规模扩大后性能下降幅度会非常有限。
5. 测试高并发场景下的表现
单条查询的测试无法暴露真实瓶颈,建议用压测工具模拟几百并发请求,观察CPU、磁盘IO的使用率。Index1这类文档扫描多的索引,高并发下磁盘会迅速饱和,导致请求延迟飙升;而Index2的IO压力小,能稳定应对高负载。
内容的提问来源于stack exchange,提问作者EV_alt
相关产品推荐
相关产品推荐

