Rails 4 Eager Load has_many单个对象的关联

时间:2015-12-16 17:26:33

标签: ruby-on-rails many-to-many has-many eager-loading ruby-on-rails-4.1

在获取带有相关记录的对象数组时,我获得了使用预先加载以避免N + 1的好处,但是在获取单个记录时使用预先加载是否很重要?

就我而言

user has_many :addresses
user has_many :skills
user has_many :devices
user has_many :authentications

在show动作中,我试图用机架迷你探测器看看是否有趣使用预先加载

User.includes(:skills, :addresses, :devices, :authentications).find(params[:id])

但我似乎有相同数量的sql请求..

有关使用此类案件的预先加载的任何建议吗?

2 个答案:

答案 0 :(得分:5)

  

在获取单个记录时使用预先加载是否很重要?

对于一级深层的协会,没有。

如果你有嵌套关联,是的。

# 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查询的方法,它们称为preloadeager_load

Preload 会为每个集合触发单个SQL查询。

Eager load 尝试构建一个大型的左连接SELECT,以检索1个查询中的所有集合。

简短版本是includes让Rails选择使用哪一个。但你可以强迫一种方式。

User.eager_load(:skills, :addresses, :devices, :authentications).find(params[:id])

应检索1个查询中的所有记录。

进一步阅读

答案 1 :(得分:3)

尝试使用Bullet gem检测未使用或缺少的预先加载。它旨在告诉您是否存在include语句浪费或N + 1查询效率低下,includes会有所帮助。

如果出现问题,可以将其配置为输出到Rails记录器以通知您。或者,您可以在浏览器中向需要优化的页面显示通知。