简体   繁体   English

Rails:ActiveRecord渴望负载和N + 1查询

[英]Rails: ActiveRecord Eager Load and N+1 Query

I'm using Rails 3.2.8, and have models 我正在使用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

in the SubjectsController, index 在SubjectsController中,索引

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

I use includes to do eager load, and In the view file, I want to display all users of a subject by this: 我使用include来进行急切的加载,并且在视图文件中,我想以此显示主题的所有用户:

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

the problem is I got db hit for every subject when display user count, which I think is the N+1 Query problem 问题是在显示用户数时,每个主题的数据库都命中了,我认为这是N + 1查询问题

anything I missed or did wrong? 我错过或做错了什么吗?

btw: I'm using MySQL 顺便说一句:我正在使用MySQL

The count method always generates SQL COUNT query. count方法始终生成SQL COUNT查询。 Since you have already loaded all the entries, try to use length to avoid extra query: 由于您已经加载了所有条目,请尝试使用length以避免额外的查询:

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

Count always do sql query and don't do any caching 计数始终执行sql查询,并且不进行任何缓存

length ans size are alias of each other, the difference between count and length is that you can pass parameter to count but to length or size and count don't do any caching. length和size是彼此的别名,count和length之间的区别是您可以传递参数进行计数,但是对于length或size和count则不进行任何缓存。

as follow 如下

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

so use any of the following statements 因此,请使用以下任何语句

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

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

First, subject.users returns an Array, which will never be nil. 首先, subject.users返回一个数组,该数组永远不会为零。 Second, try size instead of count . 其次,尝试使用size而不是count So the code could be: 因此代码可能是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM