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 $near 查询 120 万份文档耗时 6 秒