web-dev-qa-db-ja.com

Railsでは、find_eachとwhereの違いは何ですか?

Railsでは、 find_eachwhere の両方が、ActiveRecordがサポートするデータベースからデータを取得するために使用されます。

次のように、クエリ条件をwhereに渡すことができます。

c = Category.where(:name => 'Ruby', :position => 1)

そして、次のように、バッチサイズをfind_eachに渡すことができます。

Hedgehog.find_each(batch_size: 50).map{ |p| p.to_json }

しかし、次の2つのコードの違いは何ですか?

# code 1
Person.where("age > 21").find_each(batch_size: 50) do |person|
  # processing
end

# code 2
Person.where("age > 21").each do |person|
  # processing
end

コード1バッチは毎回50タプルを取得し、コード2は一度にすべてのタプルを取得しますか?詳細な説明を歓迎します。

私の意見は:

  1. wherefind_eachの両方をバッチ取得に使用できますが、find_eachを使用する場合、ユーザーはバッチサイズを定義できます。
  2. find_eachは、クエリ条件の受け渡しをサポートしていません。

私の理解が間違っている場合は修正してください。

48
coderz

アクティブなレコード関係は、すべてのレコードをメモリに自動的にロードしません。

#eachを呼び出すと、すべてのレコードがメモリにロードされます。 #find_eachを呼び出すと、レコードは指定されたバッチサイズのバッチでメモリにロードされます。

そのため、クエリがサーバーの使用可能なリソースに対してメモリが多すぎるレコード数を返す場合、#find_eachを使用するのが最適です。

基本的には、Rubyの遅延列挙#to_enum#lazy#each_sliceで使用し、次に#eachを使用するようなものです(非常に便利です)。

71
jphager2