2014-07-10 59 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

再次感謝您的回答。我做了一點性能測試,結果發現數據庫*在我的情況下是最慢的。不過,我讚賞你的想法,因爲它提供了一些值得探索的視角:-)我喜歡與我一起採取這樣的想法。一旦你使用它們... –