我有一张桌子,里面有大约 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
as 参数调用时,它会加载 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
参数是否为Integer
ActiveRecord 加载所有数据,将其转换为数组并调用 Array 的first
方法,该方法具有以下行为:http ://www.ruby-doc.org/core-1.9.3/Array.html#method -我先来