【问题标题】:Mongodb query execution take too much timeMongodb 查询执行耗时过长
【发布时间】:2018-10-01 17:12:28
【问题描述】:

我正在从事 Go 项目,我正在使用 mongodb 来存储我的数据。但是突然mongodb查询执行花了太多时间来获取数据。 我有一个名为“汽车”的集合,其中包含大约 25000 个文档,每个文档包含大约 200 个字段 (4.385KB)。我有一个这样的聚合查询:

db.cars.aggregate([
    {
        $lookup:
        {
            from: "users",
            localField: "uid",
            foreignField: "_id",
            as: "customer_info"
        }
    },{
        $unwind: "$customer_info"
    },{
        $lookup:
        {
            from: "user_addresses",
            localField: "uid",
            foreignField: "_id",
            as: "address"
        }
    },{
        $unwind: "$address"
    },{
    $lookup:
        {
            from: "models",
            localField: "_id",
            foreignField: "car_id",
            as: "model_info"
        }
    },{
    $match:{
        purchased_on:{$gt:1538392491}, 
        status:{$in:[1,2,3,4]}, 
        "customer_info.status":{$ne:9}, 
        "model_info.status":{$ne:9},
        }
    },{
        $sort:{
            arrival_time:1
        }
    },{
        $skip:0
    },{
        $limit:5
    }
])

我的文档结构是这样的:https://drive.google.com/file/d/1hM-lPwvE45_213rQDYaYuYYbt3LRTgF0/view

现在,如果在没有索引的情况下运行此查询,则加载数据大约需要 10 分钟。谁能建议我如何减少它的执行时间?

【问题讨论】:

  • 您的$match 条件应位于管道的开头以限制文档数量。
  • @AnthonyWinzlet 我的匹配过滤器取决于查找,这就是我在底部添加它的原因。还是应该有所不同?你能举个例子吗?
  • 实际上$lookup 阶段已应用于所有 25000 个文档,这使得查询变慢。因此,要限制通过$lookup 阶段的文档数量,您应该尽快使用$match。在管道的开头添加这个{ $match:{ purchased_on: { $gt:1538392491 }, status: { $in: [1, 2, 3, 4] }, }}...Query performance issue for large nested data in mongodb
  • @Swati 您能否发布一个示例文档结构和您想要获得的输出?
  • @WanBachtiar 请在此处查看文档结构。 drive.google.com/file/d/1hM-lPwvE45_213rQDYaYuYYbt3LRTgF0/…

标签: mongodb go


【解决方案1】:

要优化您的查询,需要做很多事情。我会尝试什么:

  • 正如 Anthony Winzlet 在 cmets 中所说,尽可能使用 $match 阶段作为第一阶段。这样,您可以减少传递到以下阶段的文档数量,并使用索引。

  • 假设您至少使用 3.6 mongo 版本,请使用“let/pipeline”语法 (see here) 更改查找阶段。这样,您可以在查找管道的 $match 阶段集成您的“外部过滤器”(“customer_info.status”:{$ne:9}、“model_info.status”:{$ne:9})。在正确的字段/集合上使用索引,您将在 $lookup 阶段获得一些时间/内存。

  • 尽可能晚地执行您的展开阶段,以限制传递到以下阶段的文档数量。

了解聚合管道的工作原理很重要:每个阶段接收数据、执行其工作并将数据传递到下一个阶段。因此,传递给管道的数据越少,查询速度就越快。

【讨论】:

  • 感谢您的详细回答。我会根据您的回答实施更改。
猜你喜欢
  • 2015-10-23
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 2019-12-28
  • 2019-08-02
  • 1970-01-01
  • 2011-11-03
  • 2012-11-04
相关资源
最近更新 更多