Mongodb 查询执行耗时过长

Posted

技术标签:

【中文标题】Mongodb 查询执行耗时过长【英文标题】:Mongodb query execution take too much time 【发布时间】: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/… 【参考方案1】:

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

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

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

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

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

【讨论】:

感谢您的详细回答。我会根据您的回答实施更改。

以上是关于Mongodb 查询执行耗时过长的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 查询执行时间过长

Mongodb聚合$group阶段耗时较长

Mongodb $near 查询 120 万份文档耗时 6 秒

Microsoft SQL Server:错误的查询执行计划耗时过长

Mongodb 实践

MongoDB出现CPU飚高,如何强制停止正在执行的操作