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 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 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年前

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