关于 拾年之璐

微信公众号知行校园汇,点击查看,欢迎关注

其他平台(点击蓝字可访问):

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. 模型的预加载相关推荐

  1. 三十、PHP框架Laravel学习笔记——模型的预加载

    一.预加载 预加载,就是解决关联查询中产生的 N+1 次查询带来的资源消耗 我们要获取所有书籍的作者(或拥有者),普通查询方案如下: //获取所有书籍列表 $books = Book::all(); ...

  2. Laravel5.2之模型关联预加载

    2019独角兽企业重金招聘Python工程师标准>>> 说明:本文主要说明Laravel Eloquent的延迟预加载(Eager Loading),使用延迟预加载来减少MySQL查 ...

  3. 7.1 TensorFlow笔记(基础篇):加载数据之预加载数据与填充数据

    TensorFlow加载数据 TensorFlow官方共给出三种加载数据的方式: 1. 预加载数据 2. 填充数据 预加载数据的缺点: 将数据直接嵌在数据流图中,当训练数据较大时,很消耗内存.填充的方 ...

  4. php8预加载,如何利用预加载优化Laravel Model查询详解

    前言 本文主要给大家介绍了关于利用预加载优化Laravel Model查询的相关内容,分享出来供大家参考学习,话不多说了,来一起看看详细的介绍: 介绍 对象关系映射(ORM)使数据库的工作变得非常简单 ...

  5. 基于Flask+Nginx+uWSGI实现CentOS服务端模型部署及预加载

    基于Flask+Nginx+uWSGI实现CentOS服务端模型部署及预加载http://www.manongjc.com/article/37802.html

  6. 【笔记】excel预加载word引用

    由于工作需要,做了一些excel操作word的小工具.但是头疼的是,给多个同事用的话需要挨个儿手动加载word引用. 于是乎,在网上找到了解决方案:http://www.exceloffice.net ...

  7. Fresco加载图片使用笔记--基本使用,播放动态wbep,控制播放次数,预加载,闪帧解决

    1. 简单使用 2. 属性控制 3. 播放动态webp 4. 监听webp播放及控制webp播放次数 5. 预取图片 6. 连续加载多张动图闪帧解决方案 1. 简单使用 1)添加依赖: depende ...

  8. spark 动态预加载数据_热门大数据引擎/组件概要

    热门大数据引擎/组件概要 TeraData 老牌数仓公司,已经上市十几年,数仓领导者地位(from Gartner),目前在向云端发力.主要提供一体机,MPP架构,运行稳定,之前工行用的是TD的系统, ...

  9. pytorch模型保存与加载总结

    pytorch模型保存与加载总结 模型保存与加载方式 模型保存 方式一 只存储模型中的参数,该方法速度快,占用空间少(官方推荐使用) model = VGGNet() torch.save(model ...

最新文章

  1. 为什么要在JavaScript中使用静态类型? (使用Flow进行静态打字的4部分入门)
  2. php显示网卡信息,linux如何查看网卡信息
  3. angular1x初始与架构演进(三)Ui-Router+OcLazyLoad加载模块
  4. Android4.0源码Launcher启动流程分析【android源码Launcher系列一】
  5. Spring data jpa Specification查询关于日期的范围搜索
  6. 38线性映射05——代数与代数同构
  7. 神经网络与深度学习第2章:机器学习概述 阅读提问
  8. adc0808的c语言编程51,51单片机驱动ADC0808电路图C51及汇编程序
  9. Java8新特性之双冒号(::)
  10. 原创度检测工具-文章原创度在线检测免费
  11. 简单适用的抽奖小程序
  12. 2021年年4月证券从业资格考试《金融市场基础知识》真题(考生回忆 版)
  13. 2019黑马python吾爱_最新Python黑马头条推荐系统项目视频教程
  14. BLUES吉他学习笔记001 bluesrv[1-5]
  15. 女程序员在互联网界到底有没有被歧视?
  16. 学习SEO有别的味道
  17. 国外渗透教学——CBT 国外的道德黑客Nuggets
  18. 和利时PLC主从站通讯
  19. ComingChat进入Web3.0世界的门户,未来社交新趋势!
  20. lumberjack

热门文章

  1. 不连接显示器或者HDMI欺骗器来 使用Moonlight串流游戏
  2. 决定迭代次数的两种效应
  3. Android错误日志分析
  4. [JavaScript学习-01]JavaScript实现九宫格抽奖
  5. idea打开后不显示界面,win+D快捷键解决问题
  6. 红米1_TD移动稳定版线刷包官方下载地址_JHACNBF17.0
  7. imperva ssl加速卡查询
  8. Imperva WAF使用笔记
  9. Android中第三方SDK集成之ZXing二维码扫一扫集成指南
  10. matlab实现细胞分割,MATLAB图像处理实验——细胞图像的分割和计数