Laravel 8 新增功能之如何验证N+1查询

PR 地址:github.com/laravel/framework/pull/...

Laravel 的 Eloquent ORM 是非常方便和强大的,只要在模型层做好相关配置和关联,就可以非常方便的进行查询。
但是,这无意也会给程序性能带来隐患,比如查询 N+1的问题。

举个栗子:
用户可以发表多篇博文,那么 UserModel 和 PostModel 的关系就是 1对多的关系。

// User Model
public function posts()
{
    return $this->hasMany(Post::class);
}

// UserController
// 查询一个用户
$users = User::get();
// 查询该用户的所有博文
foreach($users as $user) {
    $user->posts;
}

上面的代码就存在N+1查询的问题,应该尽量避免这种问题。如果发现呢?现在可以在 AppServiceProvider 中进行如下设置:

// User Model
public function boot()
{
    Model::preventLazyLoading(! app()->isProduction());
}

这样在有 N+1 风险的时候,就会抛出 Illuminate\Database\LazyLoadingViolationException 异常,然后再根据异常信息去解决就可以了,例如使用:

$users = User::with('posts')->get();

foreach($users as $user) {
    $user->posts;
}

with 是为了解决 N+1 而生的。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 5

搞错了吧 🤔️

3年前 评论
raybon 3年前

这才是N+1:

$users = User::get();

foreach($users as $user) {
    $user->posts
}
3年前 评论
24K大白羊 (楼主) 3年前
lddtime 3年前
zxdstyle (作者) 3年前

所以看了半天 N+1 是个啥问题?

3年前 评论

N+1会造成啥影响?

3年前 评论
24K大白羊 (楼主) 3年前

hasOne 也被检查了。

3年前 评论
zxdstyle 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!