0

だから、私はビッグデータを含むデータベースを持っています。使用するデータは現在約 2,6 GB です。

後で別のスクリプトで使用するために、すべてのデータをテキスト ファイルに書き込む必要があります。

データはファイルごとに制限され、複数の部分に分割されています。1 ファイルあたり 100 件の結果 (各ファイル約 37 MB)。それは約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

言い換えれば、すべてのファイルが書き込まれるたびに、ファイルごとの書き込み時間が大幅に増加し、スクリプトがオフコースで遅くなります。

スクリプトの構造は次のようになります。

$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);
4

1 に答える 1

1

個人的には、これを LIMIT のない単一の 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)内にifaを配置すると、よりクリーンになる可能性があり、非常に大きな数を設定する必要はありません。ここで実際のエラーが発生した場合、スクリプトを追い出す前に PHP が長時間処理を続行する可能性があります。 .whileini_set('max_execution_time', 600);

マニュアルから:

スクリプトの実行を許可する秒数を設定します。これに達すると、スクリプトは致命的なエラーを返します。デフォルトの制限は 30 秒です。存在する場合は、php.ini で定義されている max_execution_time 値です。

呼び出されると、set_time_limit() はタイムアウト カウンターをゼロから再開します。つまり、タイムアウトがデフォルトの 30 秒で、スクリプト実行の 25 秒後に set_time_limit(20) などの呼び出しが行われた場合、スクリプトはタイムアウトするまで合計 45 秒間実行されます。

于 2016-02-24T16:40:05.580 に答える