8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CakePHPでCSV出力時にメモリ不足に陥らないために

Last updated at Posted at 2018-10-30

##思わぬ落とし穴
まず、CSV出力自体はマニュアルや参考資料が豊富に揃っているのでそれほど困らないかと思います。
そう。この手軽さゆえに以下のようなケースに陥りがちです(かく言う私も・・・

・テスト環境でCSV出力を実装
・テスト環境でテストデータをもとに色々なパターンでCSV出力
・テストも問題無かったので本番環境に実装
・本番環境でCSV出力実行! ・・・しばらくグルグル・・・
・まだグルグル・・・・・・シュン・・
!!!
まさかのメモリ不足による処理落ち・・

はい。理由は本番環境での数万件のデータに対してCSV出力機能が耐え切れなくなったのですね。。
あぁ、テスト環境でダミーデータ数万件用意して負荷テストをするべきだった・・・時すでに遅し・・

##そうならないためにも
以下に、件数が多くてもデータを分割して出力することによりメモリ不足を回避する方法について
紹介したいと思います。(データの分割方法に焦点をあて、CSV出力方法については割愛します)

CakepPHP

//100件ずつ分割して
$term = 100;
$this->Model->begin();
$cnt = $this->Model->find('count');
$cnt = (int)ceil($cnt / $term);

//分割した回数分ループ
for ($k = 0; $k < $cnt; $k++) {

    //100件取り出す
    $params['order'] = ['id' => 'asc'];
    $params['offset'] = $k * $term;
    $params['limit']  = $term;
    $data = $this->Model->find('all', $params);

    foreach ($data as $i => $v) {
        //ここでCSVに書き込み
    }
}
//全て書き込みが終わったらcloseして出力
$this->Model->rollback();

以上となります。

##ポイント

  • データを分割してCSVに書き出す(分割する単位はレコードの長さなどを考慮して調整)
  • きちんとテスト環境でもダミーデータを投入して出力確認してみる
8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?