Laravel - N+1,多重关系

问题描述 投票:0回答:1

我想优化我的应用程序。多个模型中有很多相似的关系,但我找不到减少查询量的方法。

示例:

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 eager-loading select-n-plus-1
1个回答
0
投票

我建议您安装 Laravel N+1 Query Detector 软件包来帮助检测和解决 Laravel 应用程序中的 N+1 查询问题。 在您开发应用程序时,此软件包会实时监控您的查询,并在您应该添加急切加载(N+1 查询)时通知您

© www.soinside.com 2019 - 2024. All rights reserved.