Mysql 我需要一些帮助

Mysql 我需要一些帮助,mysql,ruby-on-rails,eager-loading,Mysql,Ruby On Rails,Eager Loading,最近有人告诉我,要提高性能,迫切需要加载。我已经设法从加载此页面中删除了一些查询,但我怀疑如果我能够正确加载所需的记录,我可以更有效地减少这些查询 此控制器需要加载以下所有内容才能填充视图: 学生 学生正在查看的研讨会(课堂)页面 该研讨会所包括的所有目标 目标研讨会,目标和研讨会之间的连接表。这包括“优先级”栏,该栏由教师设置,用于对目标进行排序 目标是学生,另一个连接表。包括学生在该目标上得分的“分数”栏 学生们,最后一个加入讨论会。包括一些学生可以调整的设置 控制器: def stud

最近有人告诉我,要提高性能,迫切需要加载。我已经设法从加载此页面中删除了一些查询,但我怀疑如果我能够正确加载所需的记录,我可以更有效地减少这些查询

此控制器需要加载以下所有内容才能填充视图:

  • 学生

  • 学生正在查看的研讨会(课堂)页面

  • 该研讨会所包括的所有目标

  • 目标研讨会,目标和研讨会之间的连接表。这包括“优先级”栏,该栏由教师设置,用于对目标进行排序

  • 目标是学生,另一个连接表。包括学生在该目标上得分的“分数”栏

  • 学生们,最后一个加入讨论会。包括一些学生可以调整的设置

控制器:

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_Conferences join表中。该值由教师设置)。如果有更多的空间,则该方法将查看学生得分100%的目标,并按优先级排序。(learn_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
def教学选项(学生、研讨会、列表限制)
教_opt_数组=[]
[70,99],[100100]。每个都有|
@oss.each do | os|
obj=os.objective
此分数=@student分数。通过(:objective=>obj)查找分数
如果这是你的分数
这个分数=这个分数
如果(此点>=n[0]&&此点列表限制),则设定“选择数组”。推送(obj)
终止
返回示教选择数组
终止

提前感谢您提供的任何见解!

@jeff-关于您的问题,我看不出在
@student\u分数之外会有多少查询。查找方式(:objective=>obj)
。 您的
@student\u scores
对象已经是一个ActiveRecord关系,对吗?因此您可以在此上使用
.where()
,或者
。选择{}
,而不再次点击数据库。选择将留给您一个数组,而不是AR关系,因此请小心

this_score = @student_scores.where(objectve: obj)
this_score = @student_scores.select{|score| score.objective == obj}
这些应该有效

关于top controller方法的其他一些建议-我没有看到任何防护或防御编码,因此如果这些对象中的任何一个为nil,您的
.order(:blah)
可能会出错。此外,如果它们返回nil,则依赖于其数据的后续查询可能会出错。我会选择一些
try()
s或救援

最后,只是吹毛求疵,但前两行有点难以理解,因为您可能会错误地将参数解释为应用于include和main对象:

@student = Student.includes(:objective_students).find(params[:student])
@seminar = Seminar.includes(:objective_seminars).find(params[:id])
我会把这个发现和你的主要目标放在一起,然后包括:

@student = Student.find(params[:student]).includes(:objective_students)
@seminar = Seminar.find(params[:id]).includes(:objective_seminars)
你是说“where”不会向数据库发送另一个点击,但“find_by”会发送吗?如果是这样,那是有道理的。另外,链末尾带有“includes”的语法是我第一次尝试的方式。这样就引发了一个错误。