1. 课程导入与性能工程视角
MongoDB 的索引与查询性能工程,不是“背几条索引规则”就能掌握的技能。它更像一门围绕数据访问路径展开的系统工程:同一份数据,在不同查询模式、不同索引设计、不同执行计划下,可能表现出几十倍甚至上百倍的延迟差异。本课程的目标,是让你从“会写查询”进阶到“能设计访问路径、能定位性能瓶颈、能用数据证明优化有效”。
一、先建立性能工程视角
很多开发者第一次遇到慢查询时,第一反应是“加索引”。但索引并不是越多越好:每个索引都会占用内存与磁盘,并让写入路径变长。性能工程的核心,是在读性能、写性能、存储成本与一致性之间做可量化的权衡。因此,我们需要先明确三个问题:
- 查询在做什么:是点查、范围扫描、排序、聚合,还是多条件组合?
- 数据如何被访问:走集合扫描还是索引扫描?索引是否覆盖了过滤与排序字段?
- 代价有多大:扫描了多少文档、返回了多少文档、耗时多少、是否命中内存?
这三个问题对应了本课程的主线:查询模式 → 索引结构 → 执行计划 → 度量指标 → 优化决策。索引不是孤立对象,而是查询与存储之间的“访问路径契约”。
二、核心问题域与知识框架
本课程围绕五个相互关联的问题域展开。第一是索引模型:单字段、复合、多键、文本、地理空间、哈希、通配符等索引分别适合什么查询。第二是查询形态:等值、范围、排序、投影、聚合管道如何影响索引选择。第三是执行计划:MongoDB 如何通过查询规划器选择 winning plan,以及 explain 输出中的 stage、indexBounds、keysExamined、docsExamined 等字段如何解读。第四是性能度量:延迟、吞吐、扫描效率、选择性、工作集与缓存命中率。第五是工程治理:索引生命周期、写入放大、慢查询日志、性能回归与容量评估。
下面这张图给出了本课程的整体知识框架与度量闭环。它强调:查询模式驱动索引设计,索引设计影响执行计划,执行计划产生可观测指标,指标反过来修正索引与查询。
三、性能度量:不要只看“快不快”
延迟是最直观的指标,但它不足以解释问题。一个查询从 500ms 降到 5ms,可能只是因为数据被缓存了,而不是索引变好了。因此,我们需要一组更细的度量:
| 指标 | 含义 | 优化判断 |
|---|---|---|
| executionTimeMillis | 执行阶段耗时 | 端到端延迟的主要部分 |
| totalKeysExamined | 扫描的索引键数量 | 越接近返回文档数越好 |
| totalDocsExamined | 扫描的文档数量 | 远大于返回数说明索引选择性差 |
| nReturned | 最终返回文档数 | 与扫描量对比判断效率 |
| stage | 执行阶段类型 | COLLSCAN 通常需要优化 |
一个实用的判断原则是:扫描效率 = nReturned / totalDocsExamined。如果这个比值接近 1,说明索引定位精准;如果只有 0.01,说明扫描了大量无关文档。例如,某集合有 10 万条订单,查询 {status:"PAID", city:"杭州"} 返回 200 条,但 docsExamined 为 80000,则扫描效率为 0.0025,说明缺少合适的复合索引或字段顺序不合理。
四、从“写查询”到“设计访问路径”
本课程后续会反复使用一个分析动作:用 explain("executionStats") 观察执行计划。下面是一个典型示例,用于说明我们关注什么:
db.orders.find({
status: "PAID",
createdAt: { $gt: ISODate("2024-01-01") }
}).sort({ createdAt: -1 }).explain("executionStats")
在输出中,我们重点看 winningPlan 的 stage 链、indexBounds 是否精确、totalKeysExamined 与 totalDocsExamined 是否接近 nReturned。如果出现 SORT 阶段且内存占用高,说明排序没有走索引;如果出现 COLLSCAN,说明查询没有可用索引。这些判断不依赖猜测,而是由执行计划直接给出。
五、本课程的学习目标
完成本课程后,你应该能够:
- 根据查询模式设计单字段、复合、多键、文本、地理空间等索引;
- 读懂 explain 输出,判断查询是否走索引、是否覆盖、是否排序;
- 使用 keysExamined、docsExamined、nReturned 等指标定位低效查询;
- 在读写性能之间做权衡,避免索引膨胀与写入放大;
- 建立慢查询监控、索引评审与性能回归的工程习惯。
性能工程不是一次性调优,而是持续观测、假设、验证、修正的循环。索引是手段,查询是入口,执行计划是证据,度量指标是判断依据。接下来,我们将从索引的基本结构与选择性开始,逐步建立这套可验证的性能工程方法。