如何利用预加载优化Laravel Model查询详解


Posted in PHP onAugust 11, 2017

前言

本文主要给大家介绍了关于利用预加载优化Laravel Model查询的相关内容,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍:

介绍

对象关系映射(ORM)使数据库的工作变得非常简单。 在以面向对象的方式定义数据库关系时,可以轻松查询相关的模型数据,开发人员可能不会注意底层数据库调用。

下面将通过一些例子,进一步帮助您了解如何优化查询。

假设您从数据库收到了100个对象,并且每个记录都有1个关联模型(即belongsTo)。 默认使用ORM将产生101个查询; 如下所示:

//获取已发布的100条文章
$posts = Post::limit(100)->get(); //一次查询

$authors = array_map(function($post) {
 // 对作者模型生成查询
 return $post->author->name;
}, $posts);

我们在查询时没有告诉Post模型,我们还需要所有的作者,所以每次从单个Post模型实例获取作者的名字时,都会发生单独的查询。

array_maps时发生100次查询,加上先前一次查询,累计产生101次查询。

预加载

接下来,如果我们打算使用关联的模型数据,我们可以使用预加载将该101个查询总数减少到2个查询。 只需要告诉模型你需要什么来加载。如下:

//获取已发布的100条文章 - 并预加载文章对应作者
$posts = Post::with('author')->limit(100)->get();//2次查询

$authors = array_map(function($post) {
 // 对作者模型生成查询
 return $post->author->name;//这里讲不在产生查询
}, $posts);

如果你开启了sql日志,你将看到上述预加载将只会产生两条查询:

select * from `posts`
select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [1,2,3,4,5]

如果您有多个关联模型,则可以使用数组加载它们:

$posts = App\Post::with(['author', 'comments'])->get();

接下来我们重新定义如下关系

Post -> belongsTo -> Author //每个文章只属于一个用户
Author -> hasMany -> Post //每个用户拥有多个文章
Author -> hasOne -> Profile //每个用户只有一个简介

考虑下述情况:获取已发布文章所属作者的个人简介。

//获取所有文章 - 并预加载文章对应作者
$posts = App\Post::with('author')->get();//两次查询

//根据每个 `作者` 获取其简介
$posts->map(function ($post) {
 //虽然我们直接通过$author = $post->author不会产生查询,
 //但当调用$author->profile时,每次都会产生一个新查询
 return $post->author->profile;
});

假设上述App\Post::with('author')->get()有100条记录,将会产生多少条查询呢?

通过优化预加载,我们可以避免嵌套关系中的额外查询。

//获取所有文章 - 并预加载文章对应作者及每个作者对应de profile
$posts = App\Post::with('author.profile')->get();//三次查询

$posts->map(function ($post) {
 //不在产生新查询
 return $post->author->profile;
});

你可以打开你的sql日志看到对应的三条查询。

select * from `posts` 
select * from `authors` where `authors`.`id` in (?, ?, ?, ?, ?) [.....] 
select * from `profiles` where `profiles`.`author_id` in (?, ?, ?, ?, ?) [.....]

懒惰加载

有时候您可能只需要根据条件收集相关联的模型。 在这种情况下,您可以懒惰地调用相关数据的其他查询:

$posts = App\Post::all();//一次查询

$posts->load('author.profile');//两次查询
$posts->map(function ($post) {
 //不在产生新查询
 return $post->author->profile;
});

查看您的sql日志,总共看到三个查询,但只有调用$posts->load()时才会显示。

结论

希望您更加了解有关加载型号的更多信息,并了解其在更深层次上的工作原理。 Laravel相关的文档已经很全面了,希望额外的实践练习可以帮助您更有信心优化关系查询。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

原文译自eloquent-eager-loading,简化其前面构造数据部分。

PHP 相关文章推荐
php socket方式提交的post详解
Jul 19 PHP
PHP中获取变量的变量名的一段代码的bug分析
Jul 07 PHP
那些年一起学习的PHP(三)
Mar 22 PHP
php获取本地图片文件并生成xml文件输出具体思路
Apr 27 PHP
解析在zend Farmework下如何创立一个FORM表单
Jun 28 PHP
PHP错误Cannot use object of type stdClass as array in错误的解决办法
Jun 12 PHP
解密ThinkPHP3.1.2版本之模块和操作映射
Jun 19 PHP
php导入模块文件分享
Mar 17 PHP
CodeIgniter与PHP5.6的兼容问题
Jul 16 PHP
Laravel框架生命周期与原理分析
Jun 12 PHP
PDO::_construct讲解
Jan 27 PHP
Yii框架自定义数据库操作组件示例
Nov 11 PHP
PHP实现的自定义图像居中裁剪函数示例【测试可用】
Aug 11 #PHP
Redis在Laravel项目中的应用实例详解
Aug 11 #PHP
PHP验证码无法显示的原因及解决办法
Aug 11 #PHP
php readfile()修改文件上传大小设置
Aug 11 #PHP
浅谈Laravel中的一个后期静态绑定
Aug 11 #PHP
浅谈PHP中new self()和new static()的区别
Aug 11 #PHP
php使用 readfile() 函数设置文件大小大小的方法
Aug 11 #PHP
You might like
如何让CI框架支持service层
2014/10/29 PHP
Centos下升级php5.2到php5.4全记录(编译安装)
2015/04/03 PHP
Laravel 5框架学习之表单
2015/04/08 PHP
php文件扩展名判断及获取文件扩展名的N种方法
2015/09/12 PHP
PHP使用token防止表单重复提交的方法
2016/04/07 PHP
php实现和c#一致的DES加密解密实例
2017/07/24 PHP
实例讲解PHP页面静态化
2018/02/05 PHP
PHP实现登录验证码校验功能
2018/05/17 PHP
在html页面上拖放移动标签
2010/01/08 Javascript
JQUERY操作JSON实例代码
2010/02/09 Javascript
js的写法基础分析
2011/01/17 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
2012/08/24 Javascript
浅析用prototype定义自己的方法
2013/11/14 Javascript
使用jQuery设置disabled属性与移除disabled属性
2014/08/21 Javascript
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
Labelauty?jQuery单选框/复选框美化插件分享
2015/09/26 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记6)
2015/12/20 Javascript
Jquery针对tr td的一些实用操作方法(必看篇)
2016/10/05 Javascript
D3.js中强制异步文件读取同步的几种方法
2017/02/06 Javascript
vue-cli + sass 的正确打开方式图文详解
2017/10/27 Javascript
Vue使用zTree插件封装树组件操作示例
2019/04/25 Javascript
layui实现三级导航菜单
2019/07/26 Javascript
vue ajax 拦截原理与实现方法示例
2019/11/29 Javascript
Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)
2016/09/21 Python
放弃 Python 转向 Go语言有人给出了 9 大理由
2017/10/20 Python
详解基于python的多张不同宽高图片拼接成大图
2019/09/26 Python
什么是Python中的匿名函数
2020/06/02 Python
Python使用Chrome插件实现爬虫过程图解
2020/06/09 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
Python接口自动化测试框架运行原理及流程
2020/11/30 Python
意大利团购网站:Groupon意大利
2016/10/11 全球购物
培训主管的岗位职责
2013/11/23 职场文书
住房抵押登记委托书
2014/09/27 职场文书
2014年服装销售工作总结
2014/11/27 职场文书
2015年工程部工作总结
2015/04/30 职场文书
毕业生的自我鉴定表范文
2019/05/16 职场文书