我目前正在Laravel中编写应用程序,并且正在设置一些将定期运行的计划任务(工匠命令) - 可能每月一到两次。这些任务使用CURL获取一些CSV文件,解析它们,然后将它们导入我的本地MySQL数据库。
但是,这些CSV文件中的一些非常大 - 每个大约500,000行。所以我遇到了一些内存问题。
显然我可以增加我的虚拟机中的内存,但我想知道我可以采用哪些其他方法来确保我不会耗尽内存。如果我尝试以块的形式解析文件,而不是一次解析所有文件,那么每个块是否会被视为一个单独的系统进程?或者它仍将被视为服务器的一次长时间执行?
编辑:我目前的做法。我正在使用League CSV进行解析。protected $offset = 1;
protected $parse_chunk = 10000;
public function parse()
{
$this->data = [];
$this->reader->setOffset($this->offset)->setLimit($this->parse_chunk)->fetchAll(function($row, $offset) {
array_push($this->data, array_combine($this->keys, $row));
$this->offset = $offset;
});
}
目前,上面提取前10000行,并进行我需要的处理,将它们存储在新的$data
数组中。然后将这些数据传递给Import Class,但我的脚本当前正在解析中超时。
所以上面的工作正常,但是如果我把它放在一个while
循环中来访问所有500,000条记录,那么它会占用太多内存。
我应该将每个块调度到在后台处理的队列吗?
编辑:添加了基准
我花了一些时间测试不同进程需要多长时间。解析有趣的结果。请记住,这只是解析。因此它不存储在数据库中,而是存储在内存中的数组中。
Parsing 1000 records: .017 seconds
Parsing 10,000 records: .188 seconds
Parsing 100,000 records: 2.273 seconds
Parsing 500,000 records: Never completes.
我使用上面的代码来执行此操作。什么可能导致解析在500,000条记录中花费这么长时间(或者可能失败)?