2014-07-10 28 views
0

我必须用PHP创建超过400 MB的大型csv导出文件。初始的导出文件和PHP代码的草稿允许对性能进行一些猜测。使用PHP高效创建大型csv文件

为了避免极长的处理时间,我应着眼于建立有效的导出文件,并避免PHP array -operations,因为他们在这种情况下,速度太慢。 “高效创建文件”的意思是:将大块文本附加到文件中的其他大块,每个大块快速创建。

不幸的是,“大块”相当矩形比线。建立我的导出文件将有很多线起点的开始,像这样:

Title a, Title b, Title c \n 
"2014", "07", "01" \n 
"2014", "07", "02" \n 
... 

然后我会到一个文本的“矩形”添加到行开始的权利:

Title a, Title b, Title c, extention 1, extention 2, extention 3 \n 
"2014", "07", "01", "23",  "1",   "null" \n 
"2014", "07", "02", "23",  "1",   "null" \n 
... 

如果我必须一行一行地做这件事,它会让我再次放慢脚步。所以我希望能够在文件中添加“矩形”,就像在某些文本编辑器中一样。 PHP中巨大的文本缓冲区的具体体验也有帮助,也可以工作。

因为它不是我的主机,我不知道我是否有权限调用SED/AKW。

所以问题是:可以从经验的建议如何有效地处理PHP中的大csv文件(文件块操作,文件“矩形”操作)或只是如何有效地处理PHP中的大字符串缓冲区?似乎没有字符串缓冲区的框架。

感谢您的关注:-)

注:这是不是此重复:https://stackoverflow.com/questions/19725129/creating-big-csv-file-in-windows-apache2-php

+0

只是一个想法:打开booth文本文件,寻找第一个文件的行末,附加其他文本文件的第一行并循环。 –

+0

感谢您的想法。这种“循环方法”可能会变慢。因此,我正在寻找某种“批量”或缓冲区操作。 –

+0

我想你并不是一遍又一遍地循环着。你只需要从两个文件的顶部到底部同时进行排队。 –

回答

1

的答案/评论我的问题的鼓励下,我写了一个短的基准测试。

第一个)创建每个2个文件用1万线,用100个字符的每一行。然后将它们合并为一个像拉链一样的第3个文件:

line1_1 line2_1 
line1_2 line2_2 
line1_3 line2_3 

这就是RaphaelMüller所建议的。

剖面b)填充1万行(相同的尺寸在部分1)到一个MySQL表有两列。它首先填补了第一列,增加了100万个插入语句。然后,使用一条更新声明填充第二列。像这样,我会用一个命令在一个步骤中处理多行(问题中所述的“矩形”操作)。然后在表格中准备好读取和下载合并的数据文件。

这就是Florin Asavoaie所建议的。

  • 为了用1百万行填充1个文件,每行100个字符,需要4.2秒。为了将两个文件合并到第三个文件中,需要10秒。

  • 为了用单插入语句填充每行100万行100个字符的MySQL表,它需要440秒。所以我没有测量第二步。

这是一般最终结论约的数据库或文件系统的性能。可能,数据库可以在主机上进行一些自由的优化(我没有)。

我觉得现在是有些安全的假设这样的表现顺序:

  1. RAM
  2. 文件系统
  3. 数据库

这意味着,如果你的内存是在爆破接缝因为你创建了一个导出文件,所以不要犹豫,把它分成几部分写入文件并合并它们,而不需要花费很多精力来维护内存块。

PHP不是提供复杂的低级内存块处理的语言。但最后,你不会需要它。

4

只要把所有的数据到一些SQL(SQLite的甚至会比罚款更多此目的),然后将其导出为CSV。

+0

感谢您的回答。如上所述,有没有一种方法可以在SQL中合并文本块?或者你是否建议创建并执行几条100k的INSERT和UPDATE语句? –

+0

这就是要点,插入和更新。在SQL中它的速度会更快,特别是如果您正确定义了表。即使是1百万的插入和更新,如果表格模式和一切都做得好,这并不是什么大问题。 –

+0

再次感谢您的回答。我做了一点性能测试,结果发现数据库*在我的情况下是最慢的。不过,我赞赏你的想法,因为它提供了一些值得探索的视角:-)我喜欢与我一起采取这样的想法。一旦你使用它们... –