2011-05-16 9 views
2

私は1秒ごとに収集されるセンサーデータのDBを持っています。クライアントは12時間のチャンクをCSV形式でダウンロードできるようにしたいと考えています。これはすべて完了です。非常に大きなCSVファイルを書くPHPのDB出力から

出力は悲しいほどストレートなデータではなく、CSVを作成する前に処理する必要があります(部品はDBにJSONとして保存されています)ので、テーブルをダンプすることはできません。

負荷を軽減するために、ファイルを初めてダウンロードしたときにディスクにキャッシュして、そのファイルをダウンロードするだけのリクエストがあると考えました。

file_put_contents、FILE_APPENDを使って書いてみるのはやめて、すべての行をエコーするだけですが、スクリプトを512Mに渡してもメモリが不足していても書きます。

ので、これはこれは、それも、私はそれがメモリにすべてを記憶している、すべての行でますfile_put_contentsを呼び出しています思ったように思えるない

while($stmt->fetch()){ 
    //processing code 
    $content = //CSV formatting 
    file_put_contents($pathToFile, $content, FILE_APPEND); 
} 

while($stmt->fetch()){ 
    //processing code 
    $content = //CSV formatting 
    echo $content; 
} 

動作します。

提案がありますか?

+1

代わりにfwrite()を使って1行ずつ書き込んだことがありますか? – Crashspeeder

答えて

0

問題は、file_put_contentsがすべてを一度にダンプしようとしていることです。代わりに、あなたの書式でループして、fopen、fwrite、fcloseを使うべきです。

while($stmt->fetch()){ 
    //processing code 
    $content[] = //CSV formatting 
    $file = fopen($pathToFile, a); 
    foreach($content as $line) 
    { 
     fwrite($file, $line); 
    } 
    fclose($file); 
} 

これにより、ある時点でデータに投げ込まれるデータの量が制限されます。

+0

元々は 'echo $ content'をどのように使っているのか、本当に正しいことに注意してください。ちょうど' $ content = // CSV formatting; fwrite($ file、$ content); 'を実行し、' fopen'と 'fclose'をメインループから移動します。 – chx

+0

ファイルを開いたり閉じたりするのは本当に必要ですか?それ以外の場合は、私は同意します、一度に一行でファイルに書き込んでみてください。 –

+0

レース条件は誰ですか? 2人目のユーザーがこれを読み込んで、別のユーザーがまだ読み込みを待っている場合はどうなりますか?私はデータの破損が可能であると考えています。オフィス環境では、ユーザーはすべて同時にそのようなことを見に行くかもしれないからです。 – sakatc

0

私は一度に1行書くことに完全に同意します。一度に1行以上メモリにロードされることは決してありません。私は同じことをするアプリケーションを持っています。しかし、私がこの方法で見つけた問題は、ファイルが永遠に書き終わるまでにかかることです。だから、この投稿はすでに言われていることをバックアップするだけでなく、これをスピードアップする方法について皆さんに意見を求めることです。たとえば、私のシステムでは、抑制ファイルに対してデータファイルを消去するので、一度に1行ずつ読み込み、抑制ファイル内で一致するものを探すと、一致するものが見つからなければ、新しい整理済みファイルにその行を書き込みます。しかし、50kのラインファイルは約4時間かかって終了しているので、もっと良い方法を探しています。私はいくつかの方法を試しましたが、この時点では、サプレッションファイルの各行を通して別のループを実行する必要がありますが、それでもまだ時間がかかります。

システムのメモリを管理するには、行単位で行うのが一番良い方法ですが、50k行のファイル(行は電子メールアドレスと名字です)から処理を終了するまでの処理時間を取得したいと思います可能であれば30分以内に

fyi:抑制ファイルのサイズは16,000 kbであり、memory_get_usage()によって示されるスクリプトによって使用されるメモリの合計は約35メガバイトです。

ありがとうございます!

関連する問題