0
0

More than 1 year has passed since last update.

【rails6】バッチ処理の際のfind_eachについて備忘録

Posted at

今回は、railsのバッチ処理でループ処理を実行する際にはfind_eachを使用することをおすすめされたので備忘録として書き留めておきます。

find_eachとは

find_eachとは、配列に対してループ処理を行うeachメソッドの派生版であり、取得するレコードを小分けにしてループ処理を行うことができます。
例えば、articlesテーブルに10,000個のレコードがあるとします。

articles = Article.all
articles.find_each(batch_size: 100) do |article|
  article.update!(title: 'article_test')
end

のように書くことによって、「articlesテーブルのtitleカラムの中身を'article_title'にする」というループ処理を、10,000個のレコードを100個ずつ取得し100回に分けて実行することができます。

find_eachとeachの違い

二つのメソッドの違いは単純で、
each=> 配列全てを一度にループ処理にかける
find_each=> 配列を分割して順番に(直列処理で)ループ処理にかける
となります。この、直列処理というのが重要になってきます。

find_eachのメリット

find_eachのメリットを理解するためには、CPUメモリという概念を理解しなければいけません。

CPUとは

CPUとは、コンピュータが制御や演算を行い動作命令を出す、言わば「パソコンの脳みそ」のような存在です。
CPUの性能が良いほど、処理速度が速いということなので複雑な処理もスムーズに行えるということになります。

メモリとは

メモリとは、CPUがデータを処理する際に、その作業データを一時的に保存しておく領域になります。
つまり、CPUの性能が良くても、メモリの容量が少ない場合は大量のデータを扱うような作業ができないというようなことが起こり得ます。

つまり

バッチ処理を行う際、メモリ容量の許容範囲を超えるような大量のデータを扱う場合は、OOM(Out Of Memory)エラーが出てしまうため、工夫が必要となります。
それを解決してくれるのがfind_eachということになります。前述した通り、find_eachは作業データを指定した単位で分割して直列的に処理してくれるので、OOMにならないように分割単位を設定することで、安全にバッチ処理を実行することができます。

まとめ

大量のデータをバッチで処理する時には、OOMにならないようにデータを分割処理することができるfind_eachメソッドを使おう。

0
0
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
0
0