我每秒都会收集一份传感器数据库。客户希望能够以CSV格式下载12小时的块 - 这一切都已完成。
输出很遗憾不是直接数据,需要在创建CSV之前进行处理(部件在数据库中存储为JSON) - 所以我不能只是转储表。
因此,为了减少负载,我认为第一次下载文件时,我会将其缓存到磁盘,然后再有任何请求只下载该文件。
如果我不尝试编写它(使用file_put_contents,FILE_APPEND),并且只是回显每一行就可以了,但是编写它,即使我给脚本512M它也会耗尽内存。
所以这可行
while($stmt->fetch()){
//processing code
$content = //CSV formatting
echo $content;
}
这不是
while($stmt->fetch()){
//processing code
$content = //CSV formatting
file_put_contents($pathToFile, $content, FILE_APPEND);
}
似乎我甚至认为我在每一行调用file_put_contents,它将它全部存储到内存中。
有什么建议吗?
答案 0 :(得分:0)
问题是file_put_contents试图一次性转储整个东西。相反,你应该在你的格式中循环并使用fopen,fwrite,fclose。
while($stmt->fetch()){
//processing code
$content[] = //CSV formatting
$file = fopen($pathToFile, a);
foreach($content as $line)
{
fwrite($file, $line);
}
fclose($file);
}
这将限制在任何给定时间尝试在数据中抛出的数据量。
答案 1 :(得分:0)
我完全同意一次写一行,你永远不会有这样的内存问题,因为一次只有1行加载到内存中。我有一个相同的应用程序。然而,我用这种方法发现的一个问题是该文件需要永远完成写入。所以这篇文章是为了备份已经说过的内容,还要求大家就如何提高速度提出意见?例如,我的系统根据抑制文件清理数据文件,因此我一次读取一行并在抑制文件中查找匹配项,如果未找到匹配项,则将该行写入新清理的文件中。一个50k的行文件需要大约4个小时才能完成,所以我希望找到一个更好的方法。我已经尝试了几种方法,此时我将整个抑制文件加载到内存中,以避免我的主读取循环必须在抑制文件中的每一行运行另一个循环,但即使这样仍需要几个小时。 / p>
因此,逐行是管理系统内存的最佳方式,但我希望获得50k行文件的处理时间(行是电子邮件地址,名字和姓),以便完成运行如果可能的话,不到30分钟。
fyi:抑制文件的大小为16,000 kb,而memory_get_usage()告诉脚本使用的总内存大约为35兆。
谢谢!