Laravel - N+1,多重关系

Laravel - N+1, multiple relations

提问人:ElChupacabra 提问时间:11/1/2023 更新时间:11/2/2023 访问量:28

问:

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

例:

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->imagesproduct->images

  • 从用户中选择
  • 从订单中选择
  • 从产品中选择(结合和user->productsuser->orders->products)
  • 从图像中选择(组合和 和user->imagesuser->products->imagesuser->orders->products->images)

这样,它可以从 7 个查询减少到 4 个查询。在现实生活中,我可能会下降 80-90%。

我甚至可以编写一些函数来分析所有关系并返回优化的顺序。

Laravel 急切加载 Select-N-Plus-1

评论


答:

0赞 Roman Slisarenko 11/2/2023 #1

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

enter image description here

评论

0赞 ElChupacabra 11/2/2023
不幸的是,这并不能解决我的问题。我已经知道在哪里以及为什么调用查询,但不知道如何解决这个问题。这是外部应用程序使用的 REST API,因此我不会被告知这些应用程序需要哪些数据。我需要返回的数据与当前相同,但数据库调用较少。我需要的是执行急切加载,但数据库调用比现在少。