面试题答案
一键面试- 选择字段创建专享索引:
- 条件过滤字段:
- 对于在
$match
阶段使用的字段,优先创建索引。例如,如果查询条件是{"basicInfo.age": {"$gte": 18}, "orderRecord.totalAmount": {"$gt": 100}}
,那么basicInfo.age
和orderRecord.totalAmount
字段应该考虑创建索引。因为这些字段用于过滤大量数据,索引可以帮助快速定位符合条件的文档。 - 如果有多个条件是
$and
关系,创建复合索引会更有效。例如{"basicInfo.gender": "male", "basicInfo.age": {"$gte": 30}}
,可以创建一个包含basicInfo.gender
和basicInfo.age
的复合索引。
- 对于在
- 排序字段:
- 如果查询中有
$sort
操作,对排序字段创建索引能提升性能。例如{"$sort": {"orderRecord.orderDate": -1}}
,则需要对orderRecord.orderDate
创建索引。如果同时有过滤和排序操作,并且过滤字段和排序字段有重叠部分,可以考虑将这些字段组合成复合索引,以满足两种操作的性能优化需求。
- 如果查询中有
- 条件过滤字段:
- 创建索引的顺序:
- 复合索引顺序:
- 在复合索引中,字段顺序非常关键。一般将选择性高的字段(即该字段值的唯一性较高,能快速缩小查询范围)放在前面。例如对于复合索引涉及
basicInfo.country
和basicInfo.city
,如果country
不同值的数量相对city
较少(即country
选择性低),而city
选择性高,那么复合索引应该是{basicInfo.city: 1, basicInfo.country: 1}
(假设升序排序)。这样在查询时,先根据city
快速缩小范围,再根据country
进一步过滤。 - 如果既有过滤条件又有排序条件,将过滤条件中选择性高的字段放在复合索引前面,然后是排序字段。例如查询
{"basicInfo.occupation": "engineer", "$sort": {"orderRecord.orderAmount": -1}}
,复合索引可以是{basicInfo.occupation: 1, orderRecord.orderAmount: -1}
。
- 在复合索引中,字段顺序非常关键。一般将选择性高的字段(即该字段值的唯一性较高,能快速缩小查询范围)放在前面。例如对于复合索引涉及
- 复合索引顺序:
- 创建索引示例: 在 MongoDB 中,可以使用以下命令创建索引:
// 创建单字段索引
db.users.createIndex({"basicInfo.age": 1});
// 创建复合索引
db.users.createIndex({"basicInfo.gender": 1, "basicInfo.age": 1});
在实际应用中,要通过 explain
命令来验证索引是否生效以及查询性能是否得到优化。例如:
db.users.aggregate([
{"$match": {"basicInfo.age": {"$gte": 18}, "orderRecord.totalAmount": {"$gt": 100}}},
{"$sort": {"orderRecord.orderDate": -1}}
]).explain("executionStats");
通过分析 explain
的结果,可以进一步调整索引策略,确保查询性能最优。