Ruby on rails 如何在Ruby中使用preload、includes或eager\u load优化此方法?
我想减少分配并加速Ruby worker。我一直在读关于急切加载的书,但我还没有完全理解它。方法如下:Ruby on rails 如何在Ruby中使用preload、includes或eager\u load优化此方法?,ruby-on-rails,ruby,memory,memory-management,worker,Ruby On Rails,Ruby,Memory,Memory Management,Worker,我想减少分配并加速Ruby worker。我一直在读关于急切加载的书,但我还没有完全理解它。方法如下: def perform(study_id, timestamp) study = Study.includes(:questions, :participants).find(study_id) questions = study.questions.not_random.not_paused participants = study.participants return u
def perform(study_id, timestamp)
study = Study.includes(:questions, :participants).find(study_id)
questions = study.questions.not_random.not_paused
participants = study.participants
return unless questions && participants
end_timestamp = timestamp_window(timestamp)
participants.each do |participant|
process_participant(participant, questions, timestamp, end_timestamp, study)
end
end
我希望Study.includes()
能够减少数据库查询的数量,但从Skylight来看,它似乎没有改变任何事情:
我是否错误地使用了
includes
,还是应该使用其他内容?您给出的示例似乎没有从快速加载中获得太多好处。它的用途是避免N+1查询;大概是这样的:
User.first(100).each do |user|
comments = user.comments
end
这将对100个用户进行1次查询,并对评论进行100次查询。这就是为什么它被称为N+1(这里N是100)
为了防止这种情况发生,您可以使用“快速加载”:
User.first(100).includes(:comments).each do |user|
comments = user.comments
end
现在它进行两个查询——一个是用户查询,一个是评论查询。事实上,它只进行2次查询而不是1次查询并不成问题。优化(大O)的一部分是在不同的“规模”上发现瓶颈。我不打算解释所有这些,但这是一个很好的教程:
在没有即时加载的示例中,时间复杂度为O(N),表示“线性”。所需的时间随着N的值线性增加。但是,如果使用渴望加载,则可以在不添加额外查询的情况下增加N,这是一个O(1)复杂度-恒定时间
在本例中,您有一个方法可以进行三个查询:
- 研究(找到一个)
- 相关问题
- 相关参与者
includes
从技术上讲,可能可以在一个请求中生成一个SQL查询来获取所有三个表的数据,但我认为ActiveRecord并不能为您提供任何帮助。不过,这可能没有必要。如果您不确信,可以尝试报告性能改进 您的方法如何处理
过程参与者
?它似乎在调用一个额外的查询。谢谢您的回答!