为了账号安全,请及时绑定邮箱和手机立即绑定

数据量大。迭代而不耗尽内存的最佳方法?

数据量大。迭代而不耗尽内存的最佳方法?

PHP
MMMHUHU 2023-09-08 17:14:08
使用 Laravel 6 等 Eloquent Collection 类。所以我有“很多”数据需要处理。大约 5000 行,在获取它时,会生成一个包含 5000 个模型的集合。现在,每个模型可能都有 20 个属性需要读取。有没有快速的方法来做到这一点?我目前有一个要读取的属性数组,然后像这样设置循环:\fopen()...foreach ($models as $model) {            $row = [];            foreach ($this->attributes as $attr) {                $row[] = \data_get($model, $attr);            }                \fputcsv($fh, $row);}\fclose()...$models是一个 Laravel 集合,由其中创建,EloquentModel::find($ids);其中$ids是整数数组。(来自数据库的 5000 个 ID)$this指的是包含 foreach 循环的类。attributes除了包含上面代码的函数和只是一个字符串数组的属性之外,这个类中没有其他任何东西。对于 5000 行,每行循环 20 个属性,这可能需要很长时间来处理,并且在每种情况下,这实际上都会抛出FatalErrorException:  Allowed memory size of 134217728 bytes exhausted那么检索每行属性集的最快方法是什么?我个人想不出比这个嵌套循环更快的循环了。此外,看到\fputcsv()将每一行写入文件,并且$row变量在每个循环中被覆盖,为什么我仍然得到Allowed memory size exhausted?LazyCollection 是这里的解决方案吗?
查看完整描述

1 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

这将一次处理 200 个块中的模型,从而节省大量内存。


Model::whereIn('id', $ids)->chunk(200, function($models){


      foreach ($models as $model) {

            $row = [];

            foreach ($this->attributes as $attr) {

                $row[] = \data_get($model, $attr);

            }

        

        \fputcsv($fh, $row);

      }

});


查看完整回答
反对 回复 2023-09-08
  • 1 回答
  • 0 关注
  • 76 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信