大きな子関連を持つデータベースから情報を引っ張ってくるときにincludeオプションを使うと便利だけど、よくよく考えないといけないよというお話。
データベースから情報を引っ張ってきて、その内容をcsvに吐き出す処理書いているのだけれども、全部で1000件以上あるデータを処理しようとすると、
[FATAL] failed to allocate memory
ってエラーが出てきて処理が途中で止まってしまう。。
ファイル入出力が原因か?
ループの中で毎回配列のメモリを割り当ててるのが原因か?
と、いろいろ原因を探っていったのだけれども、結局大きな原因だったのがfindのincludeオプション。
find関数を使うときに単にincludeで関連テーブルを追加で引っ張ってくるだけだと必要でないデータも一緒に読み込むのでメモリに使用される情報が非常に大きくなる。
で、上記のエラーが出たと。
とりあえずconditionsオプションに必要な情報のみincludeで指定して実行してみたところ、
以前に比べて1/5くらいの速度で処理が進むようになり、上記エラーも出なくなりました。
現状だと一度に読み込む情報量は減った分、必要な時に毎回SQLのクエリを投げて情報を引っ張ってきてるのでまだまだ改善の余地はありますが。。
select句を使って必要な情報のみとってくればもっと早くなるらしいのですが、それについては今後検討したいと思います。。
0 件のコメント:
コメントを投稿