面试题答案
一键面试1. 通过索引性能分析找出索引问题
- 开启慢查询日志:
在MongoDB配置文件中,设置
slowms
参数来定义慢查询的时间阈值(单位为毫秒)。例如,将slowms
设为100,即执行时间超过100毫秒的查询被记录为慢查询。然后重启MongoDB服务使配置生效。这样,MongoDB会将慢查询记录到日志文件中。 - 使用
explain()
方法: 对于慢查询语句,在其后面调用explain()
方法。例如,假设有一个查询db.collection.find({field1: value1, field2: value2})
,可执行db.collection.find({field1: value1, field2: value2}).explain()
。- 执行计划解读:
queryPlanner
部分:查看winningPlan
中的stage
字段。如果是COLLSCAN
,表示全表扫描,可能缺少合适索引。若为IXSCAN
,则表明使用了索引。executionStats
部分:关注nReturned
(返回文档数)、executionTimeMillis
(执行时间)、totalKeysExamined
(检查的键数)和totalDocsExamined
(检查的文档数)。若totalKeysExamined
过大,可能索引选择性差;若totalDocsExamined
接近集合文档总数,可能索引未生效。allPlansExecution
部分:比较不同执行计划的各项指标,了解是否有更优方案未被采用。
- 执行计划解读:
- 使用
db.currentOp()
方法: 执行db.currentOp()
可查看当前正在执行的操作。通过分析其中的查询信息,结合上述explain()
的分析方法,找出慢查询的索引问题。
2. 优化建议
- 创建合适索引:
根据
explain()
结果,如果发现缺少索引导致全表扫描,使用createIndex()
方法创建索引。例如,对于查询db.collection.find({field1: value1, field2: value2})
,若缺少索引,可执行db.collection.createIndex({field1: 1, field2: 1})
。这里1表示升序索引,-1表示降序索引。复合索引的字段顺序很重要,应按照查询条件中字段的使用频率和选择性来排序。 - 删除无用索引:
通过分析
explain()
结果,若发现某些索引未被使用,使用dropIndex()
方法删除。例如db.collection.dropIndex({unusedField: 1})
。无用索引不仅占用空间,还会在插入、更新和删除操作时增加开销。 - 优化复合索引:
如果复合索引使用效率低,调整索引字段顺序。例如,若查询主要基于
field1
过滤,field2
作为次要条件,应将field1
放在复合索引的首位。同时,避免创建过度冗余的复合索引,减少索引维护成本。 - 定期重建索引:
随着数据的插入、更新和删除,索引可能会碎片化,影响性能。可使用
reIndex()
方法定期重建索引,例如db.collection.reIndex()
,以提高索引的效率。但重建索引会消耗资源,应选择在系统低峰期进行。