NodeJS MongoDB查询执行缓慢

时间:2018-02-08 22:57:50

标签: node.js mongodb

我正在使用以下查询(使用NodeJS适配器)来查找集合中缺少的索引。

findIndexGaps(collection, index, from, to, callback) {
    var aggregateOptions = [
        { $group: {_id: null, min: {$min: from}, max: {$max: to} } },
        { $addFields: {rangeIds: {$range: ['$min', '$max'] } } },
        { $lookup: {from: collection, localField: 'rangeIds', foreignField: index, as: 'entries'} },
        { $project: {_id: 0, missingIds: { $setDifference: ['$rangeIds', '$entries.'+index]}}}
    ];

    this.connection.collection(collection).aggregate(aggregateOptions, {allowDiskUse: true}).toArray(...);
}

我已为集合设置了唯一索引item_id。当我使用参数from = 0to = 50和index =' item_id'时,查询会返回正确的结果。但是,执行需要将近9秒,这对于将返回最多50个结果的查询来说是不可接受的。

我查询的集合非常庞大。在撰写本文时,它包含大约4200万条目,每月增长约1000万。我可以使用小的查询范围(如上例中使用的50),但我希望这些查询尽可能高效。

导致这种放缓的原因是什么,我该如何优化呢?

3 个答案:

答案 0 :(得分:1)

我发现减速的原因是因为我在分组之前没有包含$match运算符,所以它会加载我的整个数据集,然后分组,然后搜索间隙。

这是我用来解决问题的选项:

//In aggregateOptions[]:
{ $match: { [index]: { $lte: to, $gte: from } } }

答案 1 :(得分:1)

  

然而,执行需要将近9秒,这对于将返回最多50个结果的查询来说是不可接受的。

查询的性能不取决于返回的结果数量;它取决于生成结果所执行的工作量以及执行工作时可用的资源量。

完全诊断性能需要更多信息,但我怀疑操作很慢,因为$ group阶段正在扫描集合中的所有4200万个文档并汇总结果。考虑添加初步$match阶段以过滤掉不需要汇总的数据。

您还应该确保$ lookup阶段查询在两个集合上都被编入索引(例如索引' rangeIds'在源集合上以及索引字段在外部集合上的任何内容)。

答案 2 :(得分:0)

请咨询您的平台支持团队或文档 - 集合可以处理的最佳条目数。这对我来说听起来像一个大数据案例。我认为MongoDB可能不支持超过十万个条目的东西 - 我猜测大量的数据你可能需要更快的高级数据库产品。