在获取带有相关记录的对象数组时,我得到了使用预加载以避免N + 1的好处,但是在获取单个记录时使用预加载很重要吗?
就我而言
user has_many :addresses user has_many :skills user has_many :devices user has_many :authentications
在表演动作中,我尝试使用机架迷你分析器查看是否渴望使用急切加载
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。
预加载为每个集合激发单独的SQL查询。
急切的加载尝试构造一个大规模的左联接SELECT,以在1个查询中检索所有集合。
简短的版本是includes
让Rails选择要使用的版本。但是您可以强制使用另一种方法。
User.eager_load(:skills, :addresses, :devices, :authentications).find(params[:id])
应该在1个查询中检索所有记录。
进一步阅读:
ActiveRecord查询中的“ includes”和“ preload”有什么区别?
http://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes.html
http://blog.arkency.com/2013/12/rails4-preloading/