面试题答案
一键面试- 索引设计:
- 复合索引:为了满足获取某个时间段内特定用户的特定操作类型记录的需求,创建一个复合索引
(user_id, operation_type, timestamp)
。这样的索引顺序有助于快速定位用户、操作类型,然后在这个基础上根据时间戳范围进行筛选。 - 创建索引语句:
- 复合索引:为了满足获取某个时间段内特定用户的特定操作类型记录的需求,创建一个复合索引
db.your_collection_name.createIndex({user_id: 1, operation_type: 1, timestamp: 1});
这里 1
表示升序排列,也可以根据实际情况选择降序 -1
。
- 优化查询条件:
- 查询语句:
const userId = "specific_user_id";
const operationType = "specific_operation_type";
const startTime = 1609459200; // 例如开始时间戳
const endTime = 1609545600; // 例如结束时间戳
db.your_collection_name.find({
user_id: userId,
operation_type: operationType,
timestamp: {$gte: startTime, $lte: endTime}
});
- 优化说明:
- 按照索引的顺序指定查询条件,先指定
user_id
,再operation_type
,最后timestamp
。这样可以最大程度利用索引,减少全表扫描。 - 在高并发场景下,避免使用可能导致索引失效的查询操作,比如对
timestamp
使用$not
操作符等。因为$not
操作通常不能很好地利用索引,可能导致全表扫描,增加锁争用。 - 如果可能,尽量限制查询返回的字段,只返回必要的字段,减少数据传输量,提高查询性能。例如:
- 按照索引的顺序指定查询条件,先指定
db.your_collection_name.find({
user_id: userId,
operation_type: operationType,
timestamp: {$gte: startTime, $lte: endTime}
}, {_id: 0, user_id: 1, operation_type: 1, timestamp: 1});
这里 {_id: 0, user_id: 1, operation_type: 1, timestamp: 1}
表示只返回 user_id
、operation_type
和 timestamp
字段,不返回 _id
字段。
通过上述索引设计和查询条件优化,可以在高并发读写的 MongoDB 应用场景中,有效提高查询性能,降低锁争用。