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截断标题且兼容utf8和gb2312编码
Sep 22 PHP
PHP把数字转成人民币大写的函数分享
Jun 30 PHP
PHP实现通过中文字符比率来判断垃圾评论的方法
Oct 20 PHP
PHP实现阳历到农历转换的类实例
Mar 07 PHP
php根据日期显示所在星座的方法
Jul 13 PHP
PHP使用缓存即时输出内容(output buffering)的方法
Aug 03 PHP
ThinkPHP 模板引擎使用详解
May 07 PHP
thinkphp5.0自定义验证规则使用方法
Nov 16 PHP
PHP实现绘制二叉树图形显示功能详解【包括二叉搜索树、平衡树及红黑树】
Nov 16 PHP
php爬取天猫和淘宝商品数据
Feb 23 PHP
PHP基于openssl实现的非对称加密操作示例
Jan 11 PHP
使用PHP反射机制来构造"CREATE TABLE"的sql语句
Mar 21 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/12/21 PHP
PHP函数学习之PHP函数点评
2012/07/05 PHP
php生成excel文件的简单方法
2014/02/08 PHP
PHP 类与构造函数解析
2017/02/06 PHP
PHP那些琐碎的知识点(整理)
2017/05/20 PHP
PHP中通过getopt解析GNU C风格命令行选项
2019/11/18 PHP
封装了一个js图片轮换效果的函数
2011/09/28 Javascript
jQuery通过扩展实现抖动效果的方法
2015/03/11 Javascript
JavaScript注入漏洞的原理及防范(详解)
2016/12/04 Javascript
xmlplus组件设计系列之分隔框(DividedBox)(8)
2017/05/02 Javascript
激动人心的 Angular HttpClient的源码解析
2017/07/10 Javascript
vue 实现的树形菜的实例代码
2018/03/19 Javascript
mpvue 如何使用腾讯视频插件的方法
2018/07/16 Javascript
微信小程序tabbar底部导航
2018/11/05 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
layui清除radio的选中状态实例
2019/11/14 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
详解为什么Vue中的v-if和v-for不建议一起用
2021/01/13 Vue.js
教你如何将 Sublime 3 打造成 Python/Django IDE开发利器
2014/07/04 Python
python构建自定义回调函数详解
2017/06/20 Python
python操作MySQL 模拟简单银行转账操作
2017/09/27 Python
Python实现替换文件中指定内容的方法
2018/03/19 Python
python遍历小写英文字母的方法
2019/01/02 Python
妙用itchat! python实现久坐提醒功能
2019/11/25 Python
Python编程快速上手——强口令检测算法案例分析
2020/02/29 Python
解决Keyerror ''acc'' KeyError: ''val_acc''问题
2020/06/18 Python
日常奢侈品,轻松购物:Verishop
2019/08/20 全球购物
兼职学生的自我评价
2013/11/24 职场文书
业务主管岗位职责范本
2013/12/25 职场文书
环保建议书600字
2014/05/14 职场文书
关于感恩的演讲稿400字
2014/08/26 职场文书
学习十八大的心得体会
2014/09/01 职场文书
办公室文员工作自我鉴定
2014/09/19 职场文书
党的群众路线教育实践活动剖析材料
2014/09/30 职场文书
个人年终总结怎么写
2015/03/09 职场文书
Django框架中模型的用法
2022/06/10 Python