我在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分钟来加载数据。谁能建议我如何减少执行时间?
答案 0 :(得分:2)
有许多事情可以优化您的查询。我会尝试的:
正如Anthony Winzlet在评论中所说,尽可能将$ match阶段用作第一阶段。这样,您可以减少传递到以下阶段的文档数量,并使用索引。
假设您至少使用3.6版本的mongo,请使用“ let / pipeline”语法(see here)更改查找阶段。这样,您可以在查找管道的$ match阶段集成“外部过滤器”(“ customer_info.status”:{$ ne:9},“ model_info.status”:{$ ne:9})。通过在正确的字段/集合上建立索引,您可以在$ lookup阶段获得一些时间/内存。
请尽可能早地展开阶段,以限制传递到以下阶段的文档数量。
重要的是要了解聚合管道的工作方式:每个阶段都接收数据,执行其工作并将数据传递给下一阶段。因此,传递给管道的数据越少,查询速度就越快。