在获取具有关联记录的对象数组时,我获得了使用急切加载来避免 N+1 的好处,但是在获取单个记录时使用急切加载是否重要?
就我而言
user has_many :addresses
user has_many :skills
user has_many :devices
user has_many :authentications
在表演 Action 中,我尝试使用机架迷你分析器查看使用预先加载是否有趣
User.includes(:skills, :addresses, :devices, :authentications).find(params[:id])
但我似乎有相同数量的 sql 请求..
关于在这种情况下使用预先加载的任何建议?
最佳答案
对于一层深的关联,没有。
如果您有嵌套的关联,是的。
# class User
has_many :skills
# class Skill
belongs_to :category
# this code will fire N + 1 queries for skill->category
user.skills.each do |skill|
puts skill.category
end
在这种情况下,最好预先加载
skills: :category
User.includes(skills: :category).find(id)
编辑
Rails 提供了两种方法来避免 N+1 查询,它称为
preload
ing 和 eager_load
ing。Preload 为每个集合触发单独的 SQL 查询。
Eager load 尝试构建一个大量的左连接 SELECT 来检索 1 个查询中的所有集合。
简短的版本是
includes
让 Rails 选择使用哪个。但是你可以强制一种方式或另一种方式。User.eager_load(:skills, :addresses, :devices, :authentications).find(params[:id])
应该检索 1 个查询中的所有记录。
进一步阅读 :
关于ruby-on-rails - Rails 4 Eager Load has_many 单个对象的关联,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34318342/