【问题标题】:NodeJS MongoDB Query slow to executeNodeJS MongoDB查询执行缓慢
【发布时间】:2018-07-19 15:40:19
【问题描述】:

我正在使用以下查询(使用 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 个),但我希望这些查询尽可能高效。

是什么导致了这种放缓,我该如何优化?

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

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

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

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

    您还应该确保 $lookup 阶段查询在两个集合上都建立了索引(例如,在源集合上索引“rangeIds”以及在外部集合上的任何索引字段)。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-10
          • 2020-04-23
          • 1970-01-01
          • 1970-01-01
          • 2013-11-06
          • 2019-04-04
          • 2021-08-16
          • 1970-01-01
          相关资源
          最近更新 更多