面试题答案
一键面试- 索引分析与优化
- 检查索引覆盖:确认查询中的排序字段是否在已有索引中。若没有,考虑创建涵盖排序字段的复合索引。例如,若按
created_at
字段排序,检查是否有包含created_at
的索引。若仅存在{user_id: 1}
索引,而查询为find({}).sort({created_at: 1})
,可创建{created_at: 1}
或{user_id: 1, created_at: 1}
等复合索引,确保索引覆盖排序操作,减少全表扫描。 - 索引顺序合理性:复合索引中字段顺序至关重要。将选择性高(基数大)且频繁用于筛选的字段放在前面,排序字段紧跟其后。如查询
find({status: "active"}).sort({score: -1})
,可创建{status: 1, score: -1}
索引,利于查询优化。
- 检查索引覆盖:确认查询中的排序字段是否在已有索引中。若没有,考虑创建涵盖排序字段的复合索引。例如,若按
- 分片键分析
- 分片键与排序字段关系:查看分片键与排序字段。若排序字段与分片键无关,排序时可能需从多个分片获取数据,导致性能问题。例如,分片键为
user_id
,按product_id
排序,由于不同product_id
可能分布在不同分片,获取数据时需跨分片操作。此时可考虑调整分片策略,使排序字段与分片键有一定关联,减少跨分片数据获取。 - 重新评估分片策略:依据数据访问模式和业务需求,重新评估分片策略。例如,若业务经常按日期范围查询并排序,可将日期字段作为分片键或与其他字段组成复合分片键,使数据在分片间分布更合理,利于排序操作。
- 分片键与排序字段关系:查看分片键与排序字段。若排序字段与分片键无关,排序时可能需从多个分片获取数据,导致性能问题。例如,分片键为
- 查询优化
- 限制返回字段:避免返回不必要字段,减少数据传输量。如
find({}).sort({price: 1}).project({_id: 0, name: 1, price: 1})
,仅返回name
和price
字段,而非整个文档,降低网络传输和处理开销。 - 添加筛选条件:尽量添加筛选条件缩小数据范围。例如
find({category: "electronics"}).sort({rating: -1})
,只对电子产品分类数据排序,减少参与排序的数据量。
- 限制返回字段:避免返回不必要字段,减少数据传输量。如
- 硬件与配置优化
- 内存配置:确保MongoDB有足够内存,使索引和部分热数据可驻留在内存,减少磁盘I/O。调整
wiredTiger.cache_sizeGB
参数,根据服务器内存情况合理分配给MongoDB的缓存大小。 - 硬件升级:若条件允许,升级硬件,如采用更快的磁盘(SSD)、增加内存或提升CPU性能,改善整体系统性能,加快排序操作。
- 内存配置:确保MongoDB有足够内存,使索引和部分热数据可驻留在内存,减少磁盘I/O。调整