Rails:ActiveRecord Eager Load和N + 1查询

时间:2013-01-17 06:43:53

标签: mysql ruby-on-rails ruby rails-activerecord

我正在使用Rails 3.2.8,并且有模型

class Subject < ActiveRecord::Base
  has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
  has_and_belongs_to_many :subjects
end

在SubjectsController中,索引

@subjects = Subject.includes(:users).all

我使用includes来做热切加载,在视图文件中,我希望显示主题的所有用户:

<%= subject.users.count if not subject.users.nil? %>

问题是当显示用户数时我得到每个主题的db命中,我认为是 N + 1 查询问题

我遗漏或做错了什么?

btw:我正在使用MySQL

3 个答案:

答案 0 :(得分:4)

count方法始终生成SQL COUNT查询。由于您已经加载了所有条目,因此请尝试使用length以避免额外查询:

<%= subject.users.length if not subject.users.nil? %>

答案 1 :(得分:1)

<%= subject.users.count if not subject.users.nil? %>

Count始终执行sql查询而不执行任何缓存

长度和大小是彼此的别名,计数和长度之间的差异是您可以将参数传递给count但是长度或大小和计数不会进行任何缓存。

如下

[1,2,3].count{|x| x > 2}
result => 1

所以请使用以下任何一种陈述

<%= subject.users.length if not subject.users.nil? %>

<%= subject.users.size if not subject.users.nil? %>

答案 2 :(得分:0)

首先,subject.users返回一个数组,该数组永远不会为零。 其次,请尝试size而不是count。 所以代码可以是:

<%= subject.users.size if not subject.users.empty? %>