面试题答案
一键面试监控索引基数变化的工具
- MongoDB自带命令:
db.collection.stats()
:可以获取集合的统计信息,其中包括索引相关信息,如索引大小等。例如,在mongo shell中执行db.yourCollection.stats()
,能查看集合整体状态,辅助判断索引基数变化对集合的影响。db.collection.totalIndexSize()
:直接返回集合所有索引占用的总字节数。通过定期执行此命令,观察索引大小的变化趋势,间接反映索引基数变化。
- MongoDB Compass:
- 它是MongoDB官方的可视化工具。在Compass中,可以直观地查看集合及其索引信息。在集合详情页面,能看到索引列表,并且可以查看每个索引的基数估计值等信息。通过观察这些信息随时间的变化,监控索引基数变化。
- MongoDB Enterprise Advanced:
- Ops Manager:提供了全面的监控功能。可以设置监控任务,针对索引基数等关键指标进行实时或定期监控。它能生成详细的报表和图表,展示索引基数在一段时间内的变化情况,方便分析趋势。
基于监控数据对索引进行动态调整
- 索引创建:
- 基于查询日志分析:使用
slowOpSampleRate
参数开启慢查询日志,分析慢查询语句。例如,如果经常有查询语句按user_id
和timestamp
字段过滤数据,且发现索引基数合适(通过监控工具得知),但查询性能不佳,可考虑创建复合索引db.yourCollection.createIndex({user_id: 1, timestamp: 1})
。这样能提高查询效率,因为索引基数合理时,合适的索引结构能加速查询。 - 针对新业务需求:当有新的业务功能上线,涉及到新的数据查询方式时,根据监控到的索引基数情况,及时创建新索引。比如新功能需要按
category
字段快速查找数据,若监控显示category
字段的索引基数稳定且适合索引,就创建db.yourCollection.createIndex({category: 1})
。
- 基于查询日志分析:使用
- 索引删除:
- 低基数索引:通过监控工具发现某些索引基数非常低(例如,一个索引字段只有几个固定值,且数据量较大时),这种索引可能对查询性能提升不大,反而占用额外空间和影响写操作性能。可以使用
db.yourCollection.dropIndex({lowCardinalityField: 1})
删除此类索引。 - 未使用索引:在Ops Manager或通过
db.currentOp()
命令查看当前正在运行的操作,结合查询日志,若发现某些索引长时间未被使用,且索引基数没有明显变化,可以考虑删除。例如db.yourCollection.dropIndex({unusedField: 1})
,这样能减少索引维护开销。
- 低基数索引:通过监控工具发现某些索引基数非常低(例如,一个索引字段只有几个固定值,且数据量较大时),这种索引可能对查询性能提升不大,反而占用额外空间和影响写操作性能。可以使用
- 索引重建:
- 索引碎片化:监控到索引大小异常增长,可能是索引碎片化导致。此时可以先备份数据,然后删除原索引,再重新创建索引。例如
db.yourCollection.dropIndex({fragmentedField: 1})
,然后db.yourCollection.createIndex({fragmentedField: 1})
,以优化索引结构,提高查询性能,尤其在索引基数动态变化后,重建索引可使其适应新的数据分布。 - 索引结构调整:当业务查询模式发生较大变化,原索引结构不再适用,但索引基数仍有优化空间时,可调整索引结构。比如将单字段索引改为复合索引,先删除原单字段索引
db.yourCollection.dropIndex({singleField: 1})
,再创建复合索引db.yourCollection.createIndex({field1: 1, field2: 1})
,以满足新的查询需求。
- 索引碎片化:监控到索引大小异常增长,可能是索引碎片化导致。此时可以先备份数据,然后删除原索引,再重新创建索引。例如