Laravel中的chunk组块结果集处理与注意问题


Posted in PHP onAugust 15, 2018

前言

如果你需要处理成千上万个 Eloquent 结果,可以使用 chunk 命令。chunk 方法会获取一个“组块”的 Eloquent 模型,并将其填充到给定闭包进行处理。使用 chunk 方法能够在处理大量数据集合时能够有效减少内存消耗:

Flight::chunk(200, function ($flights) {
 foreach ($flights as $flight) {
  //
 }
});

$all_ark=Arkvolume::chunk(50000, function ($flights) {
 foreach ($flights as $flight) {
  $GLOBALS['something'][] = $flight['id'];
 }
});
 
var_dump($GLOBALS['something'] );exit;

这段代码是执行一个100条的数据进行更新,当执行完成后继续后面的另一百条数据……

也就是说他每次操作的是一个数据块而不是整个数据库。

需要注意的是:当使用带筛选的条件的chunk时,如果是自更新,那么你会漏掉一些数据,接着看代码:

User::where('approved', 0)->chunk(100, function ($users) {
 foreach ($users as $user) {
 $user->update(['approved' => 1]);
 }
});

如果要运行上面的代码,并不会有报错,但是where条件是筛选approved为0的user然后将approved的值跟新为1。
在这个过程中,档第一数据库的数据被修改后,下一个数据块的数据将是在被修改后的数据中选出来的,这个时候数据变了,而page也加了1。所以执行结束后,只对数据中一半的数据进行了更新操作。

如果没有明白的话,我们来看一下chunk的底层实现。还以上面的代码为例,假如一共有400条数据,数据被按照100条进行分块处理。

page = 1: 最开始的时候page为1,选取1-100条数据进行处理;

page = 2: 这时候前一百数据的approved值全部为1,那么在次筛选的时候数据将从第101条开始,而这个时候的page=2,那么处理的数据将是第200-300之前的数据

之后依旧。

public function chunk($count, callable $callback)
{
 $results = $this->forPage($page = 1, $count)->get();
 
 while (count($results) > 0) {
  // On each chunk result set, we will pass them to the callback and then let the
  // developer take care of everything within the callback, which allows us to
  // keep the memory low for spinning through large result sets for working.
  if (call_user_func($callback, $results) === false) {
   return false;
  }
 
  $page++;
 
  $results = $this->forPage($page, $count)->get();
 }
 
 return true;
}

Laravel chunk 使用注意的问题

使用 Laravel 的 chunk 可以用来优化大结果集的查询,提供分块处理数据的方法,但是如下的例子就会有问题:

User::where('approved', 0)->chunk(100, function ($users) {
 foreach ($users as $user) {
 $user->update(['approved' => 1]);
 }
});

原因在于第一次查询:

select * from users where approved = 0 limit 100 offset 0;

update 这一批数据的 approved 为 1 之后,

再看第二次查询:

select * from users where approved = 0 limit 100 offset 100;

这个时候因为有 where approved = 0 条件并且偏移量从 100 开始,这样其实就漏掉了 100 条 approved 为 0 的数据。

所以,我们要避免使用 chunk 的时候,更改和过滤条件的字段的值。

总结

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

PHP 相关文章推荐
php高级编程-函数-郑阿奇
Jul 04 PHP
php使用base64加密解密图片示例分享
Jan 20 PHP
php生成QRcode实例
Sep 22 PHP
php静态文件生成类实例分析
Jan 03 PHP
php准确获取文件MIME类型的方法
Jun 17 PHP
PHP实现基于文本的摩斯电码生成器
Jan 11 PHP
PHP基于mssql扩展远程连接MSSQL的简单实现方法
Oct 08 PHP
CI框架AR数据库操作常用函数总结
Nov 21 PHP
redis查看连接数及php模拟并发创建redis连接的方法
Dec 15 PHP
Yii2学习笔记之汉化yii设置表单的描述(属性标签attributeLabels)
Feb 07 PHP
PHP实现的XXTEA加密解密算法示例
Aug 28 PHP
PHP微信发送推送消息乱码的解决方法
Feb 28 PHP
PHP curl批处理及多请求并发实现方法分析
Aug 15 #PHP
php使用curl_init()和curl_multi_init()多线程的速度比较详解
Aug 15 #PHP
php使用curl获取header检测开启GZip压缩的方法
Aug 15 #PHP
深入研究PHP中的preg_replace和代码执行
Aug 15 #PHP
PHP中一个有趣的preg_replace函数详解
Aug 15 #PHP
PHP使用curl_multi_select解决curl_multi网页假死问题的方法
Aug 15 #PHP
php+croppic.js实现剪切上传图片功能
Aug 14 #PHP
You might like
NT IIS下用ODBC连接数据库
2006/10/09 PHP
PHP XML操作的各种方法解析(比较详细)
2010/06/17 PHP
PHP设计模式之解释器模式的深入解析
2013/06/13 PHP
三种php连接access数据库方法
2013/11/11 PHP
php socket客户端及服务器端应用实例
2014/07/04 PHP
如何通过Linux命令行使用和运行PHP脚本
2015/07/29 PHP
开启PHP Static 关键字之旅模式
2015/11/13 PHP
PHP 的Opcache加速的使用方法
2017/12/29 PHP
多个Laravel项目如何共用migrations详解
2018/09/25 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
chrome浏览器不支持onmouseleave事件的解决技巧
2013/05/31 Javascript
js实现多选项切换导航菜单的方法
2015/02/06 Javascript
jQuery on()方法使用技巧详解
2015/04/16 Javascript
jquery实现漂亮的二级下拉菜单代码
2015/08/26 Javascript
JS+CSS实现仿msn风格选项卡效果代码
2015/10/22 Javascript
JavaScript中的ajax功能的概念和示例详解
2016/10/17 Javascript
JavaScript实现一个带AI的井字棋游戏源码
2018/05/21 Javascript
Element InputNumber 计数器的实现示例
2020/08/03 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
[08:06]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant 选手采访
2021/03/11 DOTA
python实现简单的计时器功能函数
2015/03/14 Python
python中__call__内置函数用法实例
2015/06/04 Python
python实现简单ftp客户端的方法
2015/06/28 Python
使用Python制作自动推送微信消息提醒的备忘录功能
2018/09/06 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
Selenium使用Chrome模拟手机浏览器方法解析
2020/04/10 Python
简单了解pytest测试框架setup和tearDown
2020/04/14 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
详解css position 5种不同的值的用法
2019/07/30 HTML / CSS
Html5监听手机摇一摇事件的实现
2019/11/07 HTML / CSS
职高毕业生自我鉴定
2013/10/21 职场文书
2014年预备党员学习两会心得体会
2014/03/17 职场文书
小学一年级学生评语
2014/04/22 职场文书
发布会邀请函
2015/01/31 职场文书
煤矿施工安全协议书
2016/03/22 职场文书
餐厅如何利用“营销策略”扭转亏本局面
2019/10/15 职场文书