面试题答案
一键面试1. 分析查询场景
- 范围查询:对于范围查询,例如查询某个时间段内的数据,若
created_at
字段用于此查询,应在该字段上创建单字段索引。例如在Python的pymongo
中:collection.create_index([("created_at", pymongo.ASCENDING)])
。 - 多字段联合查询:如果有查询条件是多个字段的组合,如按
category
和price
联合查询,应创建复合索引。复合索引字段顺序很重要,将选择性高(基数大)的字段放在前面。在pymongo
中:collection.create_index([("category", pymongo.ASCENDING), ("price", pymongo.ASCENDING)])
。 - 排序操作:若经常按某个字段排序,如按
views
字段降序排序,需在该字段创建索引。若排序字段同时参与范围查询,可考虑合并到复合索引中。例如:collection.create_index([("views", pymongo.DESCENDING)])
。
2. 索引覆盖
- 尽量使用索引覆盖查询,即查询的字段都包含在索引中,这样MongoDB无需回表获取数据,能大大提高查询性能。例如查询
title
和views
字段,可创建复合索引[("title", pymongo.ASCENDING), ("views", pymongo.ASCENDING)]
,若查询条件允许,可提高性能。
3. 避免冗余索引
- 冗余索引会增加存储和维护成本。例如已经有复合索引
[("a", 1), ("b", 1)]
,就无需再创建单字段索引[("a", 1)]
,因为复合索引已覆盖单字段索引功能。通过db.collection.getIndexes()
查看现有索引,避免创建冗余索引。
4. 索引维护时机
- 批量操作时:在进行大量数据插入、更新或删除操作前,若可能,先删除不必要索引,操作完成后再重建。这样可减少索引维护开销,因为批量操作时索引维护成本高。
- 定期优化:定期使用
db.collection.reIndex()
对集合重建索引,以优化索引结构,尤其是在数据量大幅变化或索引碎片化严重时。但此操作会占用较多资源,应选择系统低峰期执行。
5. 索引选择性评估
- 使用
db.collection.stats().indexDetails
查看索引选择性,选择性越高,索引效果越好。对于选择性低的索引,评估是否有必要保留,因为低选择性索引可能增加维护成本却对性能提升有限。
6. 分片与索引
- 在分片集群中,合理选择分片键很重要。若分片键选择不当,可能导致数据分布不均,影响查询性能。同时,确保索引与分片策略配合,例如在片键上创建索引,可提高跨分片查询性能。