約 500,000 人のユーザーがいるテーブルがあります。Rails 3.0 コンソールを使用して次のように入力すると、
User.first
私はすぐに結果を得る。しかし、私が入力すると
User.first(1)
数秒かかります。何が原因でしょうか?
注:同じことが間で起こります
User.last
と
User.last(1)
約 500,000 人のユーザーがいるテーブルがあります。Rails 3.0 コンソールを使用して次のように入力すると、
User.first
私はすぐに結果を得る。しかし、私が入力すると
User.first(1)
数秒かかります。何が原因でしょうか?
注:同じことが間で起こります
User.last
と
User.last(1)
Erb(Rails 3.0.7)でログ表示をオンにすると、次のようになります
1.8.7 :004 > User.first
User Load (4.3ms) SELECT `users`.* FROM `users` LIMIT 1
=> #<User id: 1, email: "user@project.ru">
1.8.7 :005 > User.first(1)
User Load (0.4ms) SELECT `users`.* FROM `users`
=> #<User id: 1, email: "user@project.ru">
1.8.7 :008 > User.first(2)
User Load (0.4ms) SELECT `users`.* FROM `users`
=> [#<User id: 1, email: "user@project.ru", #<User id: 2, email: "user@gmail.com">]
したがって、first
引数なしで呼び出すと期待どおりに機能することがわかりますが、引数として呼び出すfirst
と、number
DB のすべてのユーザーが読み込まnumber
れ、users 配列に要素のみが残ります。
最近のRailsコードでは、次first
のようになります
def first(*args)
if args.any?
if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
limit(*args).to_a
else
apply_finder_options(args.first).first
end
else
find_first
end
end
それで結構です。しかし、Rails 3.0.7 のような古いバージョンでは次のようになります。
def first(*args)
if args.any?
if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
to_a.first(*args)
else
apply_finder_options(args.first).first
end
else
find_first
end
end
first
引数がActiveRecord であるかどうかがわかるようInteger
に、すべてのデータをロードし、それを配列に変換して、first
次の動作を持つ Array のメソッドを呼び出します。 -i-ファースト