2016-02-24 3 views
0

Итак, у меня есть база данных с большими данными. Данные для использования в настоящее время составляют около 2,6 ГБ.PHP File Writing (fwrite/file_put_contents) скорость/оптимизация

Все данные должны быть записаны в текстовый файл для последующего использования в других сценариях.

Данные ограничены в файле и разбиваются на несколько частей. 100 результатов на файл (около 37 Мбайт каждого файла). Это около 71 файла.

Данные представляют собой данные json, которые сериализуются и затем зашифровываются с помощью openssl.

Данные записываются в файлы до тех пор, пока не будет достигнуто максимальное время выполнения через 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); 
} 

РАБОЧИЙ КОД ПОСЛЕ HELP

$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. Но im фактически не уверен, действительно ли это проблема, если я не сериализую ее. Мог бы попробовать. Спасибо за предложение –

ответ

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) внутри if внутри цикла while, он может быть более чистым, и вам не нужно будет устанавливать ini_set('max_execution_time', 600); на очень большое число, которое, если у вас есть настоящая ошибка, может привести к тому, что PHP продолжит обработку в течение длительного времени до выкидывая сценарий.

Из инструкции:

Установите количество секунд сценарий разрешено запускать. Если это будет достигнуто, скрипт вернет фатальную ошибку. Предел по умолчанию составляет 30 секунд или, если он существует, значение max_execution_time, определенное в php.ini.

При вызове set_time_limit() перезапускает счетчик тайм-аута с нуля. Другими словами, если таймаутом является значение по умолчанию 30 секунд и 25 секунд для выполнения скрипта, выполняется вызов типа set_time_limit (20), скрипт будет работать в общей сложности за 45 секунд до истечения времени ожидания.

+0

Я понимаю. Завтра попробуем попробовать. –

+0

Мне было бы интересно узнать, будет ли он запускаться в течение 240 секунд по умолчанию 'max_execution_time' – RiggsFolly

+0

Im определенно собираюсь сообщить вам все как можно скорее –

 Смежные вопросы

  • Нет связанных вопросов^_^