[英]N+1 query in user model
I have an issue with a N+1 in my User model that I'm not sure how to fix. 我的用户模型中存在N + 1的问题,我不确定如何解决。 The method is setup like this:
该方法是这样设置的:
has_many :group_questions, through: :groups, source: :questions
has_many :question_participants, as: :questionable
has_many :questions, through: :question_participants
# Collection of Users questions
def all_questions
group = group_questions
personal = questions
all_questions = group + personal
end
it gathers questions related to a group that a User is in, but also personal questions directed to that person. 它会收集与用户所在的组相关的问题,还会收集针对该用户的个人问题。 Finally it merges them into one array.
最后,将它们合并为一个数组。
The N+1's I'm getting are: 我得到的N + 1是:
N+1 Query detected
User => [:group_questions]
Add to your finder: :includes => [:group_questions]
User => [:questions]
Add to your finder: :includes => [:questions]
happens on this line: 发生在这条线上:
current_user.all_questions.any?
class User
scope :with_questions, -> { includes(:questions, :group_questions) }
def all_questions
# No need for variables if you only use them once!
group_questions + questions
end
end
def show
@user = User.with_questions.find(params[:id])
end
You could use default_scope
but it's not really a good idea because it will slow down the cases where you don't need the joined records. 您可以使用
default_scope
但这并不是一个好主意,因为它会减慢不需要合并记录的情况。
I just saw your comment about getting the user from current_user
. 我刚刚看到您关于从
current_user
获取用户的评论。 Although loading everything in one query would be optimal overriding the user loading in the authentication logic is a mess for a marginal performance gain. 尽管在一个查询中加载所有内容是最佳的,但在身份验证逻辑中覆盖用户的加载对于获得微不足道的性能却是一团糟。 Instead you can do it like this:
相反,您可以这样做:
@user = User.eager_load(:questions, :group_questions)
.find(current_user.id)
eager_load
will force ActiveRecord to load the records upfront in a single query. eager_load
将强制ActiveRecord在单个查询中预先加载记录。 Try playing around with joins
, includes
and eager_load
in the rails console and check the difference in the the resulting SQL queries. 尝试在rails控制台中使用
joins
, includes
和eager_load
并检查所产生的SQL查询之间的差异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.