MongoDB聚合查询过慢求助:关联SKU查询耗时优化
MongoDB聚合查询优化方案
针对1万+产品文档聚合耗时5分钟的问题,核心原因是原查询会为每个产品拉取所有符合条件的SKU文档,生成数组后再统计数量,数据传输和内存开销过大。以下是具体优化方法:
优化方案1:修改$lookup逻辑,直接统计有效SKU数量
不需要拉取所有SKU文档,而是在SKU的子管道里直接计数,减少数据传输量:
products = await this.productModel.aggregate([ { $lookup: { from: 'skus', let: { myid: '$_id' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$product', '$$myid'] }, { $gt: ['$quantity', 0.00001] }, ], }, }, }, { $count: 'validCount' } // 直接统计符合条件的SKU数量 ], as: 'skuStats', }, }, { $addFields: { id: '$_id', // 提取计数,判断是否大于0 hasValidSku: { $gt: [{ $arrayElemAt: ['$skuStats.validCount', 0] }, 0] } }, }, { $match: { hasValidSku: true } }, { $unset: 'skuStats' } // 移除不需要的统计字段 ]);
优化方案2:反向查询,先获取有效产品ID再查产品
先从SKU集合筛选并分组得到所有有有效SKU的产品ID,再用这些ID查询产品,利用索引大幅提升速度:
// 第一步:获取所有符合条件的产品ID const validProductIds = await this.skuModel.aggregate([ { $match: { quantity: { $gt: 0.00001 } } }, { $group: { _id: '$product' } }, { $project: { _id: 1 } } ]).then(res => res.map(item => item._id)); // 第二步:查询对应产品(利用_id的默认索引) const products = await this.productModel.find({ _id: { $in: validProductIds } });
关键索引优化
无论用哪种方案,都必须给SKU集合建立复合索引,加速product和quantity的过滤查询:
db.skus.createIndex({ product: 1, quantity: 1 })
这个索引会让SKU的匹配查询直接走索引,避免全表扫描,是提升速度的核心前提。
内容的提问来源于stack exchange,提问作者KLJX
相关产品推荐
相关产品推荐

