こんにちは。エンジニアの佐藤です。
ユーザ情報とイベントを紐付けたActive recordを抽出するバッチ処理を書いていたのですが、レコード数が増えた結果メモリを使い切って開発環境を一つ落ちました。
メモリを使い切ったバッチ処理はこんな感じ。
目次
テーブル構造
顧客 : 注文 = 1 対 多
注文詳細 : 注文 = 1 対 多
バッチ(一部)
1年以内にログインしたユーザを取得し、かつ購入イベントがある場合にそのイベントデータを抽出
[code lang=text] 顧客.where(1年以内にログインしたユーザ) each do |顧客|注文 = 注文.where(顧客_id: 顧客.id)
if 注文.present?
注文.each do |注文|
…
こうして複数の関連テーブルを結合したレコードを用いると(他にもいくつかのテーブルが紐付いている),メモリを使い切ることができます。
よってこのように大量のレコードを処理するには、分割する必要があります。
Railsでは`find_each’です。
説明
分割してレコードを取得して処理する。
デフォルトで1000件ずつ処理をする。
Railsドキュメントより
よってeachをfind_eachに書き換えます。
[code lang=text] 顧客.where(1年以内に来店した顧客) find_each do |顧客|注文 = 注文.where(顧客_id: 顧客.id)
if 注文.present?
注文.each do |注文|
…
これでメモリを大量消費することはないでしょう。
まとめ
大量のレコードを処理する際には、分割して処理を行う。
最後に
リンクバルではエンジニアの採用を募集しています。採用はこちら