面试题答案
一键面试设计索引优化查询性能
- 复合索引:
- 对于多字段联合查询,创建复合索引。例如,如果查询条件是
field1
、field2
和field3
的联合查询,那么创建复合索引{field1: 1, field2: 1, field3: 1}
。这里数字1
表示升序索引,若字段需要降序查询,可使用-1
。索引字段顺序很重要,将选择性高(基数大,不同值多)的字段放在前面,因为索引在匹配查询时是从左到右依次使用的。 - 如果查询还涉及范围查询,例如
field1
范围查询,field2
和field3
等值查询,那么复合索引应设计为{field1: 1, field2: 1, field3: 1}
。这样在进行范围查询时,索引能够更有效地利用。
- 对于多字段联合查询,创建复合索引。例如,如果查询条件是
- 覆盖索引:
- 如果查询返回的字段包含在索引中,创建覆盖索引。例如查询只需要
field1
、field2
和field3
字段,那么创建复合索引{field1: 1, field2: 1, field3: 1}
。这样 MongoDB 可以直接从索引中获取所需数据,而不需要回表操作,大大提高查询性能。
- 如果查询返回的字段包含在索引中,创建覆盖索引。例如查询只需要
使用监控工具验证索引优化效果
- MongoDB 自带的 Explain 工具:
- 在查询语句后使用
.explain()
方法,例如db.collection.find({query}).explain()
。它会返回查询执行计划,包括是否使用了索引、使用了什么索引、扫描文档数、返回文档数等信息。 - 执行计划分析:
- IXSCAN:表示使用了索引扫描,这是理想的情况。如果查询执行计划中出现全表扫描(COLLSCAN),说明索引没有正确使用或未创建合适索引。
- 索引选择性:查看
indexFilterSet
字段,如果为true
,说明索引有效地过滤了数据。还可以看indexBounds
了解索引的范围使用情况。
- 在查询语句后使用
- MongoDB 监控命令:
- db.currentOp():可以查看当前数据库正在执行的操作,包括查询操作。通过观察查询的执行时间等信息,判断索引优化前后的性能变化。
- db.serverStatus():提供服务器的整体状态信息,包括索引使用情况(如
indexCounters
字段下的accesses
、hits
、misses
等)。优化索引后,索引命中次数(hits
)应该增加,而未命中次数(misses
)应该减少。
- 外部监控工具:
- Mongostat:实时监控 MongoDB 的各种统计信息,如每秒的查询数、插入数、更新数等。在索引优化前后,可以通过观察查询相关指标的变化,评估索引优化对整体性能的影响。
- Mongotop:用于分析 MongoDB 实例的读写操作分布,查看哪些集合或命名空间花费了最多的读写时间。通过对比索引优化前后的
mongotop
输出,判断索引优化是否减少了特定集合的查询时间。