counter_cache has_many_through sql optimization,减少sql查询次数

时间:2011-01-15 15:03:20

标签: sql ruby-on-rails optimization activerecord model

如何优化我的SQL查询,忽略这样的情况:

  

Meeting.find(5).users.size => SELECT COUNT(*)FROM ... WHERE ...

     

User.find(123).meetings.size => SELECT COUNT(*)FROm ...... WHERE ......

我不知道如何在这里使用counter_cache。

这是我的模特关系:

class Meeting < ActiveRecord::Base
  has_many :meeting_users
  has_many :users, :through => meeting_users
end

class User < ActiveRecord::Base
  has_many :meeting_users
  has_many :meetings, :through => meeting_users
end

class Meeting_user < ActiveRecord::Base
  belongs_to :meeting
  belongs_to :user
end

最佳解决方案是什么?

如何在这里实施counter_cache?

2 个答案:

答案 0 :(得分:22)

从Rails3.0.5开始,在较新的版本中,您现在可以将计数器缓存设置为“链接器”模型,在您的情况下它将是:

class MeetingUser < ActiveRecord::Base
  belongs_to :meeting, :counter_cache => :users_count
  belongs_to :user, :counter_cache => :meetings_count
end

明确指定计数列名称很重要,否则使用的列将默认为meeting_users_count

答案 1 :(得分:1)

据我所知,您不能将counter_cachethrough关联一起使用,这就是您应该手动增加它的原因。

例如(未经测试):

class MeetingUser < ActiveRecord::Base

  ...

  after_create { |record| 
    Meeting.increment_counter(:users_count, record.meeting.id)
  }

  after_destroy { |record| 
    Meeting.decrement_counter(:users_count, record.meeting.id)
  }

end