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

ast*_*nic 5 sql optimization activerecord model ruby-on-rails

我如何优化我的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
Run Code Online (Sandbox Code Playgroud)

什么是最优解决方案?

如何在这里实现counter_cache?

Vit*_*huk 22

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

class MeetingUser < ActiveRecord::Base
  belongs_to :meeting, :counter_cache => :users_count
  belongs_to :user, :counter_cache => :meetings_count
end
Run Code Online (Sandbox Code Playgroud)

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


vis*_*ise 1

据我所知,您不能使用counter_cache关联through,这就是为什么您应该手动增加它。

例如(未经测试):

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
Run Code Online (Sandbox Code Playgroud)