数据量大。迭代的最佳方法,而不会耗尽内存?
Large amount of data. Best way to iterate over, without getting memory exhaustion?
使用 Laravel 6,等等 Eloquent 集合 classes.
所以我有“大量”数据要处理。大约 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 循环的 class。 class 除了包含上述代码的函数外,没有其他内容,而 attributes
属性 只是一个字符串数组。
对于 5000 行,每行循环 20 个属性,这可能需要很长时间来处理,并且在每种情况下这实际上都会抛出一个 FatalErrorException: Allowed memory size of 134217728 bytes exhausted
那么检索每一行的属性集的最快方法是什么?我个人想不出比这个嵌套循环更快的方法了。
此外,看到 \fputcsv()
正在将每一行写入文件,并且 $row
变量在每个循环中被覆盖,为什么我仍然得到 Allowed memory size exhausted
?
LazyCollection 会是这里的解决方案吗?
谢谢!
这将分块处理模型,一次 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);
}
});
使用 Laravel 6,等等 Eloquent 集合 classes.
所以我有“大量”数据要处理。大约 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 循环的 class。 class 除了包含上述代码的函数外,没有其他内容,而 attributes
属性 只是一个字符串数组。
对于 5000 行,每行循环 20 个属性,这可能需要很长时间来处理,并且在每种情况下这实际上都会抛出一个 FatalErrorException: Allowed memory size of 134217728 bytes exhausted
那么检索每一行的属性集的最快方法是什么?我个人想不出比这个嵌套循环更快的方法了。
此外,看到 \fputcsv()
正在将每一行写入文件,并且 $row
变量在每个循环中被覆盖,为什么我仍然得到 Allowed memory size exhausted
?
LazyCollection 会是这里的解决方案吗?
谢谢!
这将分块处理模型,一次 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);
}
});