2016-02-24 48 views
0

所以,我有一個數據庫與大數據。目前使用的數據大約爲2,6 GB。PHP文件寫入(fwrite/file_put_contents)速度/優化

所有數據需要被寫入到在其他腳本日後使用文本文件。

數據被限制爲每個文件並分成多個部分。每個文件100個結果(每個文件大約37MB)。那大約有71個文件。

該數據是正在被序列化,然後用openssl加密的json數據。

的數據被正確地寫入到文件,直到240秒後達到最大執行時間。這是後約20個文件...

好,我就可以延長該時間,但沒有那這個問題。

的問題如下:

Writing file 1-6: +/- 5 seconds 
Writing file 7-8: +/- 7 seconds 
Writing file 9-11: +/- 12 seconds 
Writing file 12-14: +/- 17 seconds 
Writing file 14-16: +/- 20 seconds 
Writing file 16-18: +/- 23 seconds 
Writing file 19-20: +/- 27 seconds 

Note: time is needed time per file 

換句話說,與每一個文件我寫,每個文件的書寫時間的推移顯著了,是什麼原因導致的腳本是緩慢offcourse。

劇本的結構有點像這樣:

$needed_files = count needed files/parts 

for ($part=1; $part<=$needed_files; $part++) { // Loop throught parts 
    $query > mysqli select data 
    $data > json_encode > serialize > openssl_encrypyt 
    file_put_contents($filename.$part, $data, LOCK_EX); 
} 

工作代碼幫助後

$notchDetails = mysqli_query($conn, "SELECT * FROM notches WHERE projectid = ".$projectid.""); 

$rec_count = 0; 
$limit = 100; 
$part = 1; 

while ($notch = mysqli_fetch_assoc($notchDetails)) { 

    $data1[] = $notch; 
    $rec_count++; 

    if ($rec_count >= $limit) { 

     $data = json_encode($data1); 
     $data = openssl_encrypt(bin2hex($data), "aes128", $pass, false, $iv); 
     $filename = $mainfolder."/".$projectfolder."/".$subfolder."/".$fname.".part".$part."".$fext; 
     file_put_contents($filename, $data, LOCK_EX); 

     $part++; 
     $rec_count = 0; 
     $data = $data1 = ""; 

    } 

} 
if ($data1 != "") { 
    $data = json_encode($data1); 
    $data = openssl_encrypt(bin2hex($data), "aes128", $pass, false, $iv); 
    $filename = $mainfolder."/".$projectfolder."/".$subfolder."/".$fname.".part".$part."".$fext; 
    file_put_contents($filename, $data, LOCK_EX); 
} 

mysqli_free_result($notchDetails); 
+1

我會從http://php.net/manual/en/mysqli-result.free.php開始 – Here2Help

+1

是不是json_encode序列化的一種方式?什麼是額外的「序列化」步驟? (不要認爲這是瓶頸,只是想知道) –

+0

因爲需要合併多個json字符串和非json字符串。但即時通訊實際上不確定如果它真的是一個問題,如果我不序列化它。可以試試。感謝您的建議 –

回答

1

我個人已經編寫這作爲一個SELECT沒有限制,然後根據一個$rec_per_file = ?;寫的輸出從單while get results

藉口內在神祕的代碼,你沒有給我們太多的線索

<?php 
//ini_set('max_execution_time', 600); // only use if you have to 

$filename = 'something'; 
$filename_suffix = 1; 

$rec_per_file = 100; 

$sql = "SELECT ...."; 

Run query 

$rec_count = 0; 

while ($row = fetch a row) { 

    $data[] = serialize > openssl_encrypyt 

    $rec_count++; 

    if ($rec_count >= $rec_per_file) { 

     $json_string = json_encode($data); 

     file_put_contents($filename.$filename_suffix, 
          $json_string, 
          LOCK_EX); 

     $filename_suffix++; // inc the suffix 
     $rec_count = 0;  // reset counter 
     $data = array(); // clear data 

     // add 30 seconds to the remaining max_execution_time 
     // or at least a number >= to the time you expect this 
     // while loop to get back to this if statement 
     set_time_limit(30); 
    } 
} 
// catch the last few rows 
$json_string = json_encode($data); 
file_put_contents($filename.$filename_suffix, $data, LOCK_EX); 

的還有我不知道你爲什麼會想serialize()json_encode()

我有一個想法,基於你對執行時間評論。如果你把一個set_time_limit(seconds)ifwhile循環內它可能是更清潔,你就不必設置ini_set('max_execution_time', 600);到一個很大的數字,如果你有一個真正的錯誤,在這裏可能會導致PHP繼續處理之前很長一段時間踢腳本。

從手冊:

默認爲60秒的腳本允許運行的數量。如果達到了,該腳本返回致命錯誤。默認限制爲30秒,如果存在,則爲php.ini中定義的max_execution_time值。

當被調用時,set_time_limit()函數重新開始從零超時計數器。換句話說,如果超時時間是默認的30秒,腳本執行時間爲25秒,則會執行一次諸如set_time_limit(20)的調用,腳本將在超時之前運行總共45秒。

+0

我明白了。明天再試一試。 –

+0

我會有興趣知道,如果像這樣運行,它將運行在默認的'max_execution_time'的240秒內。 – RiggsFolly

+0

Im definitily會讓你儘快知道 –