0
让说我有以下型号:自参照协会:N + 1问题
class Strategy < ActiveRecord::Base
belongs_to :user
has_many :snapshots, :class_name => 'Strategy', :foreign_key => 'master_id'
belongs_to :master, :class_name => 'Strategy', :counter_cache => :snapshots_count
scope :master_only, -> { where(:master_id => nil) }
end
因此,任何用户都可以创建的Strategy
主实例的快照在控制器我收到的所有“主” 的Strategy
实例属于current_user
@strategies = current_user.strategies.master_only.includes(:user,:snapshots)
滑轨正确地加载strategies
和snapshots
在两个查询而获取user
在单独的查询每个快照因而引入(在此特定情况下N + 2)N + 1个问题:
Strategy Load (0.3ms) SELECT `strategies`.* FROM `strategies` WHERE strategies`.`user_id` = 2 AND `strategies`.`master_id` IS NULL LIMIT 10 OFFSET 0
User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IN (2)
Strategy Load (0.8ms) SELECT `strategies`.* FROM `strategies` WHERE `strategies`.`master_id` IN (56, 8, 55, 1, 58, 57, 24, 22)
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
....
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 5 LIMIT 1
有一种方法更有效地加载快照用户?
太棒了!我不知道我能做'.includes(快照::用户)'。在你提供的表单中它不会改变结果SQL(N + 1仍然发生),但是这个语句解决了这个问题:'@strategies = current_user.strategies.master_only.includes(:user,snapshots::user)'。你能否更新你的答案来反映这一点,所以我可以接受它? – 2014-10-26 19:28:27
谢谢,我已经更新了答案。 – Alireza 2014-10-26 19:47:12