我想优化我的应用程序。多个模型中有很多相似的关系,但我找不到减少查询量的方法。
示例:
class User extends Model {
$with = ['images', 'products', 'orders'];
//relations goes here
}
class Product extends Model {
$with = ['images'];
//relations goes here
}
class Order extends Model {
$with = ['products'];
//relations goes here
}
在这种情况下,当我调用
User::all()
时,这些是正在调用的查询:
由于产品与订单和都相关,因此用户查询被调用两次。图像查询称为三元组。这只是一个简化的示例,但在实际场景中,我有大约 180 个查询,它们从 10-20 个表中调用 select,我确信它可以优化,但我不知道如何优化。我知道我可以简单地删除
$with
并使用 ->with()
指定我实际需要加载的模型。问题是这个项目真的很大,有超过 1000 个端点,验证每个端点都需要几个月的时间,更不用说其他正在收集数据的模块了。
我知道急切加载的顺序会有所不同,因为加载
user->images
时 laravel 还不知道 product->images
ID 是什么。因此,并非所有表都只能有一个查询,但如果按此顺序加载,应该没问题:
user->products
和 user->orders->products
)user->images
和user->products->images
和user->orders->products->images
)这样可以从 7 个查询减少到 4 个查询。在现实生活中,我可能会下降 80-90%。
我什至可以编写一些函数来分析所有关系并返回优化的顺序。
我建议您安装 Laravel N+1 Query Detector 软件包来帮助检测和解决 Laravel 应用程序中的 N+1 查询问题。 在您开发应用程序时,此软件包会实时监控您的查询,并在您应该添加急切加载(N+1 查询)时通知您。