【Laravel笔记】12. 模型的预加载
关于 拾年之璐
微信公众号:知行校园汇,点击查看,欢迎关注
其他平台(点击蓝字可访问):
GitHub | Gitee | 哔哩哔哩 | 语雀 | 简书 | 微信小程序 | 知行达摩院
本文专栏:Laravel 点击查看系列文章
1、预加载,就是解决关联查询中产生的N+1 次查询带来的资源消耗。
所谓 N+1 条,就是起初获取全部数据的 1 条和,遍历的 N 条。看下面的示例。
比如在下面的关联查询
中,要获取所有书籍的作者(或拥有者),即通过获取所有的书籍,查询每个书籍对应的所有者:
//获取所有书籍列表
$books = Book::all();
//遍历每一本书
foreach ($books as $book) {//每一本书的关联用户的姓名(关联查询)DebugBar::info($book->user->username);
}
其执行的SQL为:
select * from `laravel_books`select * from `laravel_users` where `laravel_users`.`id` = 19 limit 1select * from `laravel_users` where `laravel_users`.`id` = 20 limit 1select * from `laravel_users` where `laravel_users`.`id` = 21 limit 1select * from `laravel_users` where `laravel_users`.`id` = 24 limit 1select * from `laravel_users` where `laravel_users`.`id` = 25 limit 1select * from `laravel_users` where `laravel_users`.`id` = 26 limit 1select * from `laravel_users` where `laravel_users`.`id` = 27 limit 1select * from `laravel_users` where `laravel_users`.`id` = 29 limit 1......
通过调试器 Debugbar 中 SQL 语句的分析,发现包含十多条 SQL 语句。
这是因为,在关联查询时,每遍历一次(foreach循环)就会执行一遍 SQL 语句,导致性能欠佳。
2、使用 with()
关键字,进行预载入设置,提前将 SQL 整合,即可大大减少执行的SQL语句数目。如:
//with 关键字预载入
$books = Book::with('user')->get();
foreach ($books as $book) {DebugBar::info($book->user->username);
}
相比较于原来的例子,只增加了with关键字。
这是,执行的结果是一致的。而执行的SQL为:
select * from `laravel_books`select * from `laravel_users` where `laravel_users`.`id` in (19, 20, 21, 24, 25, 26, 27, 29, 79)
此时的SQL 执行数目为:1+1 条。
另外,使用 with()
关键字也支持设置显示的列,比如:
$books = Book::with('user:id,username')->get();
foreach ($books as $book) {DebugBar::info($book->user);
}
其输出的结果,是个模型User,并且只包含两个属性:
另外,使用 with()
关键字也支持数组,多个关联:with(['book', 'prifile' ])
。
3、如果每次都必须使用预载入进行关联查询,可以在模型中定义:
即在books模型中,写入:
protected $with = ['user'];
然后就可以像上面的第一种方法使用(不需要加with()方法
),即可自动使用预加载。
4、也可以使用闭包的方式,进行预载入筛选
查询:
//闭包查询
$books = Book::with(['user' => function ($query) {$query->where('id', 19);//这样写可能没啥意义,看结果吧
}])->get();//输出
foreach ($books as $book) {DebugBar::info($book->user);
}//可以增加个为空的判断:
foreach ($books as $book) {if($book->user != null){DebugBar::info($book->user->username);}
}
首先看其执行的SQL语句:
select * from `laravel_books`select * from `laravel_users` where `laravel_users`.`id` in (19, 20, 21, 24, 25, 26, 27, 29, 79) and `id` = 19
然后其执行结果为:
预载入筛选不可以使用limit、take 方法。
5、在上面的所有示例中,预加载是回提前进行管理执行的。
但有时,可能会产生逻辑判断,进而判断是否查询数据。为了避免自愿性能的浪费,可以采用延迟预载入
:
$books = Book::all();//这里的with()方法省了,用下面的load延迟加载。if (true) {$books = $books->load('user'); //这个load也可以使用闭包,如://load(['user' => function () {// 条件信息//}])foreach ($books as $book) {DebugBar::info($book->user->username);}
}
6、使用loadCount()方法,可以实现延迟关联统计;
$users = User::all();
if (true) {return $users->loadCount('book');
}
执行的SQL为:
select * from `laravel_users`select `id`, (select count(*) from `laravel_books` where `laravel_users`.`id` = `laravel_books`.`user_id`) as `book_count` from `laravel_users` where `laravel_users`.`id` in (19, 20, 21, 24, 25, 26, 27, 29, 76, 79, 80, 99, 100, 101, 106)
执行结果为:
[{"id": 19,"username": "蜡笔小新",......"book_count": 5},{"id": 20,"username": "路飞",......"book_count": 1},{"id": 21,"username": "黑崎一护",......"book_count": 1},{"id": 24,"username": "小明",......"book_count": 1},{"id": 25,"username": "孙悟饭",......"book_count": 1},......
]
以上。
【Laravel笔记】12. 模型的预加载相关推荐
- 三十、PHP框架Laravel学习笔记——模型的预加载
一.预加载 预加载,就是解决关联查询中产生的 N+1 次查询带来的资源消耗 我们要获取所有书籍的作者(或拥有者),普通查询方案如下: //获取所有书籍列表 $books = Book::all(); ...
- Laravel5.2之模型关联预加载
2019独角兽企业重金招聘Python工程师标准>>> 说明:本文主要说明Laravel Eloquent的延迟预加载(Eager Loading),使用延迟预加载来减少MySQL查 ...
- 7.1 TensorFlow笔记(基础篇):加载数据之预加载数据与填充数据
TensorFlow加载数据 TensorFlow官方共给出三种加载数据的方式: 1. 预加载数据 2. 填充数据 预加载数据的缺点: 将数据直接嵌在数据流图中,当训练数据较大时,很消耗内存.填充的方 ...
- php8预加载,如何利用预加载优化Laravel Model查询详解
前言 本文主要给大家介绍了关于利用预加载优化Laravel Model查询的相关内容,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍: 介绍 对象关系映射(ORM)使数据库的工作变得非常简单 ...
- 基于Flask+Nginx+uWSGI实现CentOS服务端模型部署及预加载
基于Flask+Nginx+uWSGI实现CentOS服务端模型部署及预加载http://www.manongjc.com/article/37802.html
- 【笔记】excel预加载word引用
由于工作需要,做了一些excel操作word的小工具.但是头疼的是,给多个同事用的话需要挨个儿手动加载word引用. 于是乎,在网上找到了解决方案:http://www.exceloffice.net ...
- Fresco加载图片使用笔记--基本使用,播放动态wbep,控制播放次数,预加载,闪帧解决
1. 简单使用 2. 属性控制 3. 播放动态webp 4. 监听webp播放及控制webp播放次数 5. 预取图片 6. 连续加载多张动图闪帧解决方案 1. 简单使用 1)添加依赖: depende ...
- spark 动态预加载数据_热门大数据引擎/组件概要
热门大数据引擎/组件概要 TeraData 老牌数仓公司,已经上市十几年,数仓领导者地位(from Gartner),目前在向云端发力.主要提供一体机,MPP架构,运行稳定,之前工行用的是TD的系统, ...
- pytorch模型保存与加载总结
pytorch模型保存与加载总结 模型保存与加载方式 模型保存 方式一 只存储模型中的参数,该方法速度快,占用空间少(官方推荐使用) model = VGGNet() torch.save(model ...
最新文章
- 为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)
- php显示网卡信息,linux如何查看网卡信息
- angular1x初始与架构演进(三)Ui-Router+OcLazyLoad加载模块
- Android4.0源码Launcher启动流程分析【android源码Launcher系列一】
- Spring data jpa Specification查询关于日期的范围搜索
- 38线性映射05——代数与代数同构
- 神经网络与深度学习第2章:机器学习概述 阅读提问
- adc0808的c语言编程51,51单片机驱动ADC0808电路图C51及汇编程序
- Java8新特性之双冒号(::)
- 原创度检测工具-文章原创度在线检测免费
- 简单适用的抽奖小程序
- 2021年年4月证券从业资格考试《金融市场基础知识》真题(考生回忆 版)
- 2019黑马python吾爱_最新Python黑马头条推荐系统项目视频教程
- BLUES吉他学习笔记001 bluesrv[1-5]
- 女程序员在互联网界到底有没有被歧视?
- 学习SEO有别的味道
- 国外渗透教学——CBT 国外的道德黑客Nuggets
- 和利时PLC主从站通讯
- ComingChat进入Web3.0世界的门户,未来社交新趋势!
- lumberjack
热门文章
- 不连接显示器或者HDMI欺骗器来 使用Moonlight串流游戏
- 决定迭代次数的两种效应
- Android错误日志分析
- [JavaScript学习-01]JavaScript实现九宫格抽奖
- idea打开后不显示界面,win+D快捷键解决问题
- 红米1_TD移动稳定版线刷包官方下载地址_JHACNBF17.0
- imperva ssl加速卡查询
- Imperva WAF使用笔记
- Android中第三方SDK集成之ZXing二维码扫一扫集成指南
- matlab实现细胞分割,MATLAB图像处理实验——细胞图像的分割和计数