上周线上 MongoDB 聚合查询慢到崩溃,10 分钟都跑不出结果,用户疯狂投诉。排查发现是聚合管道没加索引,优化后查询时间直接降到 5 秒,快了 120 倍!
问题出在哪?$match 和 $sort 阶段没用上索引,MongoDB 要全表扫描,慢得要命。
错误写法:
db.orders.aggregate([ { $group: { _id: "$user_id", total: { $sum: "$amount" } } }, { $match: { total: { $gt: 1000 } } }, { $sort: { total: -1 } }])这个聚合管道有 3 个致命问题:
1. $match 放在 $group 后面 - 先聚合全表,再过滤,浪费资源
2. 没有索引支持 - user_id 字段没索引,全表扫描
3. $sort 在最后 - 内存排序,数据量大会崩溃
正确写法:
// 1. 先创建索引db.orders.createIndex({ user_id: 1, amount: 1 })// 2. 优化聚合管道db.orders.aggregate([ { $match: { user_id: { $exists: true } } }, { $sort: { user_id: 1, amount: -1 } }, { $group: { _id: "$user_id", total: { $sum: "$amount" } } }, { $match: { total: { $gt: 1000 } } }, { $sort: { total: -1 } }])3 个关键优化:
1️⃣ $match 前置 - 先过滤数据,减少处理量
2️⃣ 创建复合索引 - user_id + amount 复合索引,覆盖查询
3️⃣ $sort 紧跟 $match - 利用索引排序,避免内存排序
提示:聚合管道优化核心:$match 前置 + 索引覆盖 + 减少数据传输MongoDB 会自动优化管道顺序,但手动优化效果更好
实战效果对比:
优化前:查询 10 分钟超时,CPU 100%,内存爆满优化后:查询 5 秒完成,CPU 10%,内存正常
千万数据量下,性能提升 120 倍!
聚合管道优化原则:
✅ $match 尽量前置,减少数据量✅ $project 尽早使用,只保留需要的字段✅ $sort 紧跟 $match,利用索引✅ 创建复合索引,覆盖查询条件✅ 避免 $lookup 嵌套,改用多次查询
常见误区:
❌ 以为 MongoDB 会自动优化所有管道 - 手动优化效果更好❌ $match 随便放 - 位置很重要,影响性能❌ 不创建索引 - 聚合查询更需要索引支持
总结:
MongoDB 聚合查询慢?记住 3 招:$match 前置 + 创建索引 + 减少数据量。优化管道顺序,性能直接起飞!
#程序员# #数据库#
转载请注明来自海坡下载,本文标题:《优化聚合(MongoDB聚合查询10分钟超时)》
京公网安备11000000000001号
京ICP备11000001号
还没有评论,来说两句吧...