我一直在尝试使用范围链接 Arel 查询,而不仅仅是使用我在控制器中编写的一些冗长的逻辑。但是范围比获取所有记录然后用一些逻辑筛选它们要慢。那么,我想知道为什么范围更好。
这就是我正在做的事情:
- 一个问题有很多答案
- 一个答案属于一个问题
- 一个问题有一个“question_type”列,我用它来对其进行排序
首先,范围方式...
有问题.rb:
scope :answered, joins(:answers).order('answers.created_at desc')
scope :dogs, where(:question_type => "dogs")
scope :cats, where(:question_type => "cats")
scope :mermaids, where(:question_type => "mermaids")
在 questions_controller.rb 中:
@dogs_recently_answered = Question.answered.dogs.uniq[0..9]
@cats_recently_answered = Question.answered.cats.uniq[0..9]
@mermaids_recently_answered = Question.answered.mermaids.uniq[0..9]
然后在视图中,我循环遍历这些实例变量(现在是最多包含 10 个元素的数组)并显示结果。
以下是加载页面所需的时间(五次不同):
在 535 毫秒内完成 200 次 OK(查看次数:189.6 毫秒 | ActiveRecord:46.2 毫秒)
在 573 毫秒内完成 200 次 OK(查看次数:186.0 毫秒 | ActiveRecord:46.3 毫秒)
在 577 毫秒内完成 200 次 OK(查看次数:189.0 毫秒 | ActiveRecord:45.6 毫秒)
在 532 毫秒内完成 200 次 OK(查看次数:182.9 毫秒 | ActiveRecord:46.1 毫秒)
在 577 毫秒内完成 200 次 OK(查看次数:186.7 毫秒 | ActiveRecord:46.9 毫秒)
现在,凌乱的控制器方式......
@answers = Answer.order("created_at desc")
@all_answered = []
@answers.each {|answer| @all_answered << answer.question}
@recently_answered = @all_answered.uniq
@dogs_all_answered = []
@cats_all_answered = []
@mermaids_all_answered = []
@recently_answered.each do |q|
if q.question_type == "dogs"
@dogs_all_answered << q
@dogs_recently_answered = @dogs_all_answered[0..9]
elsif q.question_type == "cats"
@cats_all_answered << q
@cats_recently_answered = @cats_all_answered[0..9]
elsif q.question_type == "mermaids"
@mermaids_all_answered << q
@mermaids_recently_answered = @mermaids_all_answered[0..9]
end
end
以下是现在加载页面所需的时间(五次不同):
在 475 毫秒内完成 200 次 OK(查看次数:196.5 毫秒 | ActiveRecord:34.5 毫秒)
在 480 毫秒内完成 200 次 OK(查看次数:200.4 毫秒 | ActiveRecord:36.4 毫秒)
在 434 毫秒内完成 200 次 OK(查看次数:198.2 毫秒 | ActiveRecord:35.8 毫秒)
在 475 毫秒内完成 200 次 OK(查看次数:194.2 毫秒 | ActiveRecord:36.4 毫秒)
在 475 毫秒内完成 200 次 OK(查看次数:195.0 毫秒 | ActiveRecord:35.4 毫秒)
所以...
除了可读性之外,通过范围磨练查询还能获得什么?当有更多记录时,它最终会变得更快吗?