2010-09-29 79 views
0

正在将数据导出到csv。 25000条记录后,内存耗尽。 内存限制增加可以。php并行处理或一个接一个处理文件的过程

如果我有100000行,我可以将它写为4进程。 先写25000行,再下25000然后下...

这是可能的csv出口? 这会有什么好处吗?或者这是相同的输出整个数据?

任何多处理或并行处理都有一些优势吗?

+0

也许有代码效率可以改善。我们可以看看相关的代码吗? – webbiedave 2010-09-29 14:47:53

+0

只是选项卡分隔foreach循环中的字段 – zod 2010-09-29 14:56:45

回答

0

嗯,这取决于你如何生成CSV。

假设你是在做数据库查询(或其他导入)的结果,你可以尝试使用流而不是构建然后返回。

基本上,你首先关闭输出缓冲:

while(ob_get_level() > 0) { 
    ob_end_flush(); 
} 

然后,当你正在建设中,但按行回声出来行:

foreach ($rows as $row) { 
    echo '"'.$row[0].'","'.$row[1].'"'."\n"; 
} 

这样一来,你不是在PHP中使用太多的内存。

你也可以将数据写入到一个临时文件,然后流该文件回:

$file = tmpfile(); 
foreach ($rows as $row) { 
    fputcsv($file, $row); 
} 
rewind($file); 
fpassthru($file); // Sends the file to the client 
fclose($file); 

但同样,这一切都取决于你在做什么。这听起来像你在建立一个字符串中的CSV(这是吃你所有的记忆)。这就是为什么我建议这两个选项......

0

问题是如果你分叉进程,你不得不担心清理它的孩子,你仍然使用相同数量的内存。最终你受机器内存的限制,但如果你不想有条件地增加基于迭代次数的php memory_limit,那么分叉可能是一条可行的路。

如果您使用--enable-pcntl和编译了PHP,那么您就很好 - 否则,您将无法分叉进程。一种解决方法是拥有一个主脚本来委托其他脚本的执行,但是如果您使用反引号或shell()exec()(或类似的东西),它会开始变得sl and不乐,您将不得不采取很多步骤来确保你的命令不被污染/利用。

+0

pcntl启用。什么是sigchild?那我找不到。我会看 – zod 2010-09-29 14:57:58

+0

当你使用信号处理程序时,'--enable-sigchild'允许父母接收SIGCHLD信号,例如告诉它孩子已经退出,所以你的程序不会变成僵尸。 – mway 2010-09-29 15:20:10

相关问题