3

と呼ばれる2つのモデルがあると仮定するUserPost

「プランA」と「プランB」のどちらがパフォーマンス(高速)が優れていますか?

「プランA」

コントローラ

@users = User.find_all_by_country(params[:country])
@posts = Post.find_all_by_category(params[:category])

見る

<%= @users.count.to_s %>
<%= @posts.count.to_s %>

"次のプラン"

コントローラ

@users = User.find_all_by_country(params[:country])
@posts = Post.find_all_by_category(params[:category])

見る

<%= @users.length.to_s %>
<%= @posts.length.to_s %>
4

2 に答える 2

15

ルビーではcount、、、lengthおよびsizeすべてが配列に関してほぼ同じことを行います。詳細については、こちらをご覧ください。

ただし、ActiveRecordオブジェクトを使用する場合は、countよりも優れておりlengthsizeさらに優れています。

find_all_by_countryダム配列を返すので、そのメソッドを使用しないでください(常に配列を返すため)。代わりに、を使用してwhere(country: params[:country])ください。

CodeSchoolのRailsのベストプラクティススライドnº93にそれ自体を語らせます(そして、ここでそれを再現することで彼らが私に怒らないことを願っています)。

ここに画像の説明を入力してください

画像が削除された場合に備えて、基本的には次のようになります。

  1. length常にすべてのレコードをプルしてから、配列で.lengthを呼び出します-悪い

  2. count常にカウントクエリを実行します-良い

  3. sizeキャッシュカウンターがある場合はキャッシュを調べ、そうでない場合はカウントクエリを実行します-最適

于 2013-02-10T04:33:09.930 に答える
1

どちらも同じで、count引数はなく、ActiveRecordオブジェクトではなく、lengthRuby配列(magicメソッドによって返される)で呼び出すのと同じです。find_*

とはいえ、一致するレコードの数だけに関心がある場合は、どちらの方法もこれを行うための最悪の方法です。

結果セット全体をインスタンス化してその長さを見つける代わりに.count、実際のActiveRecordリレーションで使用します。

@num_users = User.where(country: params[:country]).count
@num_posts = Post.where(category: params[:category]).count

これは実際にselect count(*) fromは完全select * fromではなくとして実行され、結果の数に応じてはるかに高速になります。

于 2013-02-10T03:50:16.930 に答える