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 协议》,转载必须注明作者和本文链接
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

搞错了吧 🤔️

2年前 评论
raybon 2年前

这才是N+1:

$users = User::get();

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

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

2年前 评论

N+1会造成啥影响?

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

hasOne 也被检查了。

2年前 评论
zxdstyle 2年前

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