提问人:ElChupacabra 提问时间:11/1/2023 更新时间:11/2/2023 访问量:28
Laravel - N+1,多重关系
Laravel - N+1, multiple relations
问:
我想优化我的应用程序。在多个模型中有很多类似的关系,但我找不到减少查询量的方法。
例:
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,我确信它可以优化,但我不知道如何优化。我知道我可以简单地删除并使用指定我实际需要加载的模型。问题是这个项目真的很大,有超过 1000 个端点,验证每个端点需要几个月的时间,更不用说其他正在收集数据的模块了。$with
->with()
我知道急切加载的顺序会有所不同,因为在加载时,laravel 还不知道什么是 ID。因此,并非所有表都只能有一个查询,但如果按此顺序加载,则应该没问题:user->images
product->images
- 从用户中选择
- 从订单中选择
- 从产品中选择(结合和
user->products
user->orders->products
) - 从图像中选择(组合和 和
user->images
user->products->images
user->orders->products->images
)
这样,它可以从 7 个查询减少到 4 个查询。在现实生活中,我可能会下降 80-90%。
我甚至可以编写一些函数来分析所有关系并返回优化的顺序。
答:
0赞
Roman Slisarenko
11/2/2023
#1
我建议您安装 Laravel N+1 Query Detector 软件包,以帮助检测和解决其 Laravel 应用程序中的 N+1 查询问题。 此包在开发应用程序时实时监视查询,并在何时应添加预先加载(N+1 查询)时通知您。
评论
0赞
ElChupacabra
11/2/2023
不幸的是,这并不能解决我的问题。我已经知道在哪里以及为什么调用查询,但不知道如何解决这个问题。这是外部应用程序使用的 REST API,因此我不会被告知这些应用程序需要哪些数据。我需要返回的数据与当前相同,但数据库调用较少。我需要的是执行急切加载,但数据库调用比现在少。
评论