ActiveRecordで大量レコードを処理するとき
ActiveRecordで、複数レコードを処理するときには、allを使うと厳しい。
Employee.all.each {|row|
p row #このあたりで何か処理をする
}
これだと、一度すべて配列に入って処理が行われる。データベースなんだから大量にレコードがあるかもしれない。あっという間にメモリを消費しちゃう。
find_eachを使うといいと言う
そういう時のために、find_eachがある。
Employee.find_each(:batch_size=>2){|row|
p row
}
バッチサイズはデフォルト1000で1000レコードずつ処理をする。1000レコードでもカラムの内容によっては重すぎるだろうから、適宜バッチサイズを小さくすると良い。サンプルではテストしやすいようにバッチサイズを2にしている。
ところが、find_eachはソートが効かないという
ソートが効かないというが、なぜか。SQLをダンプをするとわかる。find_each(:batch_size=>2) を流すとこういうSQLが流れている。
SELECT `employees`.* FROM `employees` WHERE (`employees`.`id` > 22) ORDER BY `employees`.`id` ASC LIMIT 2
つまりIDのカラムを使って、ページングっぽい動きをしている。IDでソートをして、最後に取得したIDよりも大きなレコードを、バッチサイズ分もらってきているというわけです。ソートが効かないけど、ID順であることは分かる。