【发布时间】:2017-08-07 17:24:52
【问题描述】:
我最近被告知急切加载及其在提高性能方面的必要性。我已经设法从加载此页面中删除了一些查询,但我怀疑如果我可以正确地急切加载所需的记录,我可以进一步减少它们。
此控制器需要加载以下所有内容来填充视图:
一个学生
学生正在查看的研讨会(班级)页面
该研讨会包含的所有目标
objective_seminars,目标和研讨会之间的连接表。这包括由教师设置并用于对目标进行排序的“优先级”列。
objective_students,另一个连接表。包括学生在该目标上的分数的“分”列。
seminar_students,最后一个连接表。包括一些学生可以调整的设置。
控制器:
def student_view
@student = Student.includes(:objective_students).find(params[:student])
@seminar = Seminar.includes(:objective_seminars).find(params[:id])
@oss = @seminar.objective_seminars.includes(:objective).order(:priority)
@objectives = @seminar.objectives.order(:name)
objective_ids = @objectives.map(&:id)
@student_scores = @student.objective_students.where(:objective_id => objective_ids)
@ss = @student.seminar_students.find_by(:seminar => @seminar)
@teacher = @seminar.user
@teach_options = teach_options(@student, @seminar, 5)
@learn_options = learn_options(@student, @seminar, 5)
end
下面的方法是发生大量重复查询的地方,我认为这些重复查询应该通过预先加载来消除。这种方法为学生提供了六个选项,因此她可以选择一个目标来教她的同学。该方法首先查看学生得分在 75% 到 99% 之间的目标。在该括号内,它们也按“优先级”排序(来自objective_seminars 连接表。此值由老师设置。)如果还有更多空间,则该方法会查看学生得分为100%的目标,排序按优先级。 (learn_options 方法实际上和这个方法是一样的,只是括号号不同。)
teach_options 方法:
def teach_options(student, seminar, list_limit)
teach_opt_array = []
[[70,99],[100,100]].each do |n|
@oss.each do |os|
obj = os.objective
this_score = @student_scores.find_by(:objective => obj)
if this_score
this_points = this_score.points
teach_opt_array.push(obj) if (this_points >= n[0] && this_points <= n[1])
end
end
break if teach_opt_array.length > list_limit
end
return teach_opt_array
end
提前感谢您的任何见解!
【问题讨论】:
标签: mysql ruby-on-rails eager-loading