什么是N+1问题,如何解决 Laravel 的 N+1 问题?
一、N+1问题
介绍
在基本级别,ORM 是 “懒惰” 加载相关的模型数据。但是,ORM 应该如何知道你的意图?在查询模型后,您可能永远不会真正使用相关模型的数据。不优化查询被称为 “N + 1” 问题。当您使用对象来表示查询时,您可能在不知情的情况下进行查询。
想象一下,您收到了100个来自数据库的对象,并且每条记录都有1个关联的模型(即belongsTo)。使用ORM默认会产生101条查询; 对原始100条记录 进行一次查询,如果访问了模型对象上的相关数据,则对每条记录进行附加查询。在伪代码中,假设您要列出所有已发布帖子的发布作者。从一组帖子(每个帖子有一位作者),您可以得到一个作者姓名列表,如下所示:
$posts = Post::published()->get(); // 一次查询
$authors = array_map(function($post) {
// 生成对作者模型的查询
return $post->author->name;
}, $posts);
我们并没有告诉模型我们需要所有作者,因此每次从各个Post 模型实例中获取作者姓名时都会发生单独的查询 。
解决
预加载功能
使用with()方法指定想要预加载的关联:
$users = User::where(“age”, “>”, 18)
->with(“hasBalance”)
->select();
hasBalance 是什么呢?
它是在User模型中定义的一个方法:
class User extends Model
{
// …
// User模型与Balance 模型进行一对一关联
public function hasBalance()
{
return $this->hasOne(Balance::class, “user_id”, “user_id”);
}
}
通过这个方法让User 模型与Balance 模型进行一对一关联。
延伸阅读:
二、N+1 问题由来
假设需要现在需要查找模型 A 的 n 条数据,而模型 A 又关联了另外多个的模型,这里假设 A 关联了模型 B 和 C. 现在需要查找 n 条 A 的记录(这里需要 1 条 SQL 语句,例如 select * from A ),同时把这 n 条记录关联的 B, C 记录也查出来(这里需要 n 条查询 B 的语句和 n 条查询 C 的语句),于是最后需要的 SQL 语句数目为 2n + 1。
将 2n 抽象出来,假设需要查找的是 n 条 A 的记录(count(SQL) = 1),同时需要把与 A 关联的 k 个模型的记录也查找处理出来( count(SQL) = n * k ), 设 n * k = N, 最后查询的 SQL 语句数目,即 N + 1。

猜你喜欢LIKE
相关推荐HOT
更多>>
为什么要学IO模型?
一、要学IO模型的原因1、理解应用程序性能IO操作是网络应用程序中的关键部分,它涉及数据的输入和输出。了解不同的IO模型可以帮助开发人员更好...详情>>
2023-10-15 20:56:04
网站域名有www没有www区别?
一、网站域名有www没有www区别区别:主机记录也就是域名前缀不同,以aliyun.com为例网站域名带www:域名前缀为www,解析后的域名为www.iyun.com...详情>>
2023-10-15 17:02:21
gulp与webpack的区别?
一、gulp与webpack的区别gulpgulp强调的是前端开发的工作流程,我们可以通过配置一系列的task,定义task处理的事务(例如文件压缩合并、雪碧图...详情>>
2023-10-15 14:45:09
insmod 和 modprobe有什么区别?
一、insmod 和 modprobe的区别insmod和modprobe都是在Linux系统中加载内核模块的命令,它们之间的区别如下:1、命令格式不同insmod命令的语法格...详情>>
2023-10-15 14:09:11热门推荐
网站间隙性502怎么解决?
沸Python中动态编译函数compile参数filename的作用是什么?
热Mysql为什么只能支持2000w左右的数据量?
热为什么使用红黑树以及如何使用红黑树?
新HBase、TiDB、TDengine有什么优势?
为什么要学IO模型?
python中 from…import… 、from…import * 与import的区别?
AliSQL和OceanBase是什么关系?
APP开发的核心是什么?
什么是Sanity check,其作用是什么?
什么是Binder?
web前端开发学习路线?
Android开发手机APP软件需要做哪些准备?
网站域名有www没有www区别?
技术干货






