优化以下代码

时间:2013-10-22 07:48:11

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.2 ruby-1.9.3

我有两个活跃记录StudentDemographicsStudentWeeklyReport都有has_many这样的关系:

class StudentDemographics < ActiveRecord::Base
  has_many :student_weekly_reports, :foreign_key => :student_id
end

我必须在最近五周的研讨会上用最新的一个来检查每个学生的分数。如果结果为true,则学生应处于活动状态,否则处于非活动状态。我有以下代码。在这里,我重复每个日期的循环。 @distinct是一系列日期。

 for i in 0...@distinct.length
     active = 0
     inactive = 0
     sum = safe.length
     @students = StudentDemographics.where("date <= ?", @distinct[i]).select("student_id") - safe
     @students.each do |student|
        @stu = StudentWeeklyReport.where(:student_id => student.student_id).select("student_id,golden_eggs").last(5)
            if @stu.length > 4
                if @stu[4].golden_eggs > @stu[0].golden_eggs
                  safe << student
                  active += 1
                else
                  inactive += 1
                end
            else
                safe << student
                active += 1
            end
      end
      @active[i] = active + sum
      @inactive[i] = inactive
end

表现不佳。这需要超过3秒的时间。我的mysql数据库在StudentWeeklyReports表中有13600,在StudentDemographics表中有2000。任何人都可以建议如何优化以下代码?

2 个答案:

答案 0 :(得分:1)

     @students = StudentDemographics.includes(:student_weekly_reports) - safe
 for i in 0...@distinct.length
     active = inactive = 0
     @students.each do |student|
        next if student.date > @distinct[i]
        @stu = student.student_weekly_reports.select("golden_eggs").last(5)
            if @stu.length > 4 && (@stu[4].golden_eggs <= @stu[0].golden_eggs)
                inactive += 1
            else
                safe << student
                active += 1
            end
      end
      @active[i] = active + safe.length
      @inactive[i] = inactive
end

答案 1 :(得分:0)

@students = StudentDemographics.includes(:student_weekly_reports).where("date <= ?", @distinct.min).select("student_id")
# The above line will fetch all the necessary records you require 

for i in 0...@distinct.length
 active = inactive = 0
 @students = @student.select { |student_demographics| student_demographics.date <= @distinct[i] } - safe
 @students.each do |student|
   @stu = student.student_weekly_reports.select("golden_eggs").last(5)
   if @stu.length > 4 and (@stu[4].golden_eggs <= @stu[0].golden_eggs)
     inactive += 1
   else
     safe << student
     active += 1
   end
  end
  @active[i] = active + safe.length
  @inactive[i] = inactive
end