数据库
MongoDB学习记录优化实验:提升用户学习轨迹查询效率
问题背景
用户学习轨迹数据(包括学习时长、访问页面、笔记编辑记录等)日均新增5000+条,采用MySQL单表存储时,按用户ID+时间范围查询的平均耗时达320ms,高峰期甚至超过500ms,影响「学习数据分析」功能的用户体验。
迁移方案
优化效果对比
经验总结
- MongoDB集合设计(用户学习轨迹集合):
// 集合结构设计
db.learning_tracks.insertOne({
"user_id": 12345,
"tracks": [
{
"action": "view_note",
"resource_id": 789,
"resource_type": "note",
"start_time": ISODate("2025-07-20T14:30:00Z"),
"duration": 180,
"device": "pc"
},
{
"action": "edit_report",
"resource_id": 456,
"resource_type": "report",
"start_time": ISODate("2025-07-20T15:10:00Z"),
"duration": 420,
"device": "pc"
}
],
"date": ISODate("2025-07-20T00:00:00Z"),
"created_at": ISODate("2025-07-20T23:59:59Z")
});
- 创建索引优化查询:
// 按用户ID+日期查询索引
db.learning_tracks.createIndex({
"user_id": 1,
"date": -1
});
// 按资源类型+时间范围查询索引
db.learning_tracks.createIndex({
"tracks.resource_type": 1,
"tracks.start_time": -1
});
- PHP查询代码实现:
// 初始化MongoDB客户端
$client = new MongoDB\Client("mongodb://localhost:27017");
$collection = $client->zxpn->learning_tracks;
// 查询用户7月20日学习轨迹
$filter = [
'user_id' => 12345,
'date' => ['$gte' => new MongoDB\BSON\UTCDateTime(strtotime('2025-07-20') * 1000)]
];
$options = [
'projection' => ['tracks' => 1, '_id' => 0],
'sort' => ['date' => -1]
];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $collection->find($filter, $options);
$tracks = iterator_to_array($cursor);
指标 | MySQL存储 | MongoDB存储 | 提升比例 |
单用户日轨迹查询耗时 | 320ms | 45ms | 85.9% |
多用户轨迹统计耗时 | 850ms | 120ms | 85.9% |
数据插入QPS | 1200 | 3500+ | 191.7% |
存储占用空间 | 12GB | 8.5GB | 29.2% |
- 非结构化/半结构化数据(如用户行为轨迹)更适合MongoDB的文档存储模式,避免MySQL表结构频繁变更
- 嵌入式文档设计可减少关联查询,将用户单日轨迹聚合存储,提升查询效率
- 合理的索引设计是MongoDB性能优化的核心,需根据实际查询场景创建复合索引
分享至: