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 相关文章推荐
PHP4实际应用经验篇(8)
Oct 09 PHP
图片存储与浏览一例(Linux+Apache+PHP+MySQL)
Oct 09 PHP
php调用mysql数据 dbclass类
May 07 PHP
php GUID生成函数和类
Mar 10 PHP
destoon常用的安全设置概述
Jun 21 PHP
PHP实现视频文件上传完整实例
Aug 28 PHP
PHP PDO fetch 模式各种参数的输出结果一览
Jan 07 PHP
PHP创建PowerPoint2007文档的方法
Dec 10 PHP
PHP上传Excel文件导入数据到MySQL数据库示例
Oct 25 PHP
yii2.0整合阿里云oss删除单个文件的方法
Sep 19 PHP
Laravel 5.2 文档 数据库 ―― 起步介绍
Oct 21 PHP
laravel5.6中的外键约束示例
Oct 23 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之sphinx
2013/05/15 PHP
php判断某个方法是否存在函数function_exists (),method_exists()与is_callable()区别与用法解析
2020/04/20 PHP
用js实现的仿sohu博客更换页面风格(简单版)
2007/03/22 Javascript
js字符编码函数区别分析
2008/06/05 Javascript
JavaScript类和继承 prototype属性
2010/09/03 Javascript
jquery按回车提交数据的代码示例
2013/11/05 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
Nodejs极简入门教程(三):进程
2014/10/27 NodeJs
javascript中innerText和innerHTML属性用法实例分析
2015/05/13 Javascript
ajax的分页查询示例(不刷新页面)
2017/01/11 Javascript
100多个基础常用JS函数和语法集合大全
2017/02/16 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
Vue中v-show添加表达式的问题(判断是否显示)
2018/03/26 Javascript
MVVM框架下实现分页功能示例
2018/06/14 Javascript
在Vue中使用icon 字体图标的方法
2019/06/14 Javascript
vue props default Array或是Object的正确写法说明
2020/07/30 Javascript
Python写的服务监控程序实例
2015/01/31 Python
Python随手笔记之标准类型内建函数
2015/12/02 Python
Python微信公众号开发平台
2018/01/25 Python
浅谈python3.x pool.map()方法的实质
2019/01/16 Python
Python变量作用域LEGB用法解析
2020/02/04 Python
python+django+selenium搭建简易自动化测试
2020/08/19 Python
职高毕业生自我鉴定
2013/10/21 职场文书
市场开发与营销专业求职信
2013/12/31 职场文书
社区工作者思想汇报
2014/01/13 职场文书
迟到早退检讨书
2014/02/10 职场文书
小区物业门卫岗位职责
2014/04/10 职场文书
售后服务承诺书模板
2014/05/21 职场文书
2014国庆黄金周超市促销活动方案
2014/09/21 职场文书
领导班子民主生活会整改措施(工商局)
2014/09/21 职场文书
有限公司股东合作协议书
2014/10/29 职场文书
公司股东出资证明书
2014/11/01 职场文书
2016教师节感恩话语
2015/12/09 职场文书
承诺书的签字人,需不需要承担相应的责任?
2019/07/09 职场文书
教你怎么用Python处理excel实现自动化办公
2021/04/30 Python
MySQL插入数据与查询数据
2022/03/25 MySQL