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 相关文章推荐
如何去掉文章里的 html 语法
Oct 09 PHP
第二章 PHP入门基础之php代码写法
Dec 30 PHP
PHP中copy on write写时复制机制介绍
May 13 PHP
PHP中使用SimpleXML检查XML文件结构实例
Jan 07 PHP
Yii学习总结之安装配置
Feb 22 PHP
变量在 PHP7 内部的实现(一)
Dec 21 PHP
php使用curl并发减少后端访问时间的方法分析
May 12 PHP
深入理解php printf() 输出格式化的字符串
May 23 PHP
PHP编程实现多维数组按照某个键值排序的方法小结【2种方法】
Apr 27 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
May 29 PHP
thinkPHP事务操作简单案例分析
Oct 17 PHP
php操作redis数据库常见方法实例总结
Feb 20 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
PHP新手上路(三)
2006/10/09 PHP
php预定义常量
2006/12/25 PHP
PHP中error_log()函数的使用方法
2015/01/20 PHP
在Mac OS上编译安装Nginx+PHP+MariaDB开发环境的教程
2016/02/23 PHP
PHP如何开启Opcache功能提升程序处理效率
2020/04/27 PHP
利用json获取字符出现次数的代码
2012/03/22 Javascript
使用JSLint提高JS代码质量方法分享
2013/12/16 Javascript
jquery操作复选框(checkbox)的12个小技巧总结
2014/02/04 Javascript
网页实时显示服务器时间和javscript自运行时钟
2014/06/09 Javascript
js预加载图片方法汇总
2015/06/15 Javascript
JS实现新浪微博效果带遮罩层的弹出框代码
2015/10/12 Javascript
JavaScript字符串常用的方法
2016/03/10 Javascript
数组Array的排序sort方法
2017/02/17 Javascript
Chrome调试折腾记之JS断点调试技巧
2017/09/11 Javascript
解决vue打包之后静态资源图片失效的问题
2018/02/21 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
JavaScript实现连连看连线算法
2019/01/05 Javascript
Python时区设置方法与pytz查询时区教程
2013/11/27 Python
tensorflow实现图像的裁剪和填充方法
2018/07/27 Python
Python 创建新文件时避免覆盖已有的同名文件的解决方法
2018/11/16 Python
Python 运行.py文件和交互式运行代码的区别详解
2019/07/02 Python
Python使用scrapy爬取阳光热线问政平台过程解析
2019/08/14 Python
Window系统下Python如何安装OpenCV库
2020/03/05 Python
python中slice参数过长的处理方法及实例
2020/12/15 Python
CSS3中的注音对齐属性ruby-align用法指南
2016/07/01 HTML / CSS
基于CSS3实现图片模糊过滤效果
2015/11/19 HTML / CSS
荷兰包包购物网站:The Little Green Bag
2018/03/17 全球购物
SHEIN美国:购买时髦的女性服装
2020/12/02 全球购物
一套中级Java程序员笔试题
2015/01/14 面试题
在校生钳工实习自我鉴定
2013/09/19 职场文书
国培计划培训感言
2014/03/11 职场文书
中学生操行评语
2014/04/24 职场文书
敬老院院长事迹材料
2014/05/21 职场文书
政府四风问题整改措施
2014/10/04 职场文书
物业接待员岗位职责
2015/04/15 职场文书
2016年大学生暑期社会实践活动总结
2016/04/06 职场文书