これは取得したデータすべてにActiveRecordオブジェクトを生成していることが原因でもあるようです。
なので対策として考えられるのは、生成するオブジェクトの数を減らす方法があります。
これにはfind_eachを使うと実現できます。
find_eachは指定した件数づつ(デフォルトでは1000件)データを取得して、その分だけのActiveRecordオブジェクトを生成します。
find_eachに関しては、過去に紹介していますので、そちらをご覧ください。
大量のデータをActiveRecordで処理するとき
find_eachはソート順を指定できないという欠点があります。
もう一つの方法としてActiveRecordオブジェクトを生成せずに配列なりハッシュなり、ActiveRecordよりも軽いオブジェクトを生成する方法があります。
これには、pluckを使えます。
以下のような感じで利用します。
Order.where( amount: 1000 ).pluck( :order_no, :name, :address ) # => [["O123", "テスト太郎", "トーキョー"],["O456", "テスト花子", "オーサカ"]]
pluckの方では、ソート順は指定できます。
pluckに複数のカラムを指定できるのは、Rails4.0からのようで3.2では一つのカラムしか指定できません。
3.2でpluckで複数のカラムを指定するには、以下の方法でpluck_allという複数カラムを利用できるようなpluckを定義するパッチをあてる方法があります。
http://meltingice.net/2013/06/11/pluck-multiple-columns-rails/
こちらではハッシュのやり方ではハッシュでデータを取得します。
Order.where( amount: 1000 ).pluck_all( :order_no, :name, :address ) # => [{:order_no => "O123", :name => "テスト太郎", :address => "トーキョー"}, {:order_no => "O456", :name => "テスト花子", :address => "オーサカ"}]
もう一つの方法でmultipluckというgemを使う方法もあります。
https://github.com/hanzq/multipluck
こちらは私は試していないのですが、Rails4.0と同じ感じ使えそうなので将来のアップデートを見据えるとこちらもよさそうな気がします。
で、find_eachとpluckのどちらが速いかなのですが、私が試した数万件のデータを処理するケースではだいたい同じぐらいでした。
どちらもeachでまわすよりかは、断然早くなっています。
なのでどちらを利用するかはケースバイケースなのかなぁという感じです。
0 件のコメント:
コメントを投稿