From 946b0833fd65928e35e3a83afadf99ea96f31a53 Mon Sep 17 00:00:00 2001 From: Nelson Jovel Date: Tue, 26 Dec 2023 21:01:12 -0800 Subject: [PATCH] perf: reduce time spent in sql query for student response rate --- app/models/student_response_rate_calculator.rb | 13 +++++++------ app/models/survey_item_response.rb | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/app/models/student_response_rate_calculator.rb b/app/models/student_response_rate_calculator.rb index 198ef9a9..3aebc169 100644 --- a/app/models/student_response_rate_calculator.rb +++ b/app/models/student_response_rate_calculator.rb @@ -42,12 +42,13 @@ class StudentResponseRateCalculator < ResponseRateCalculator threshold = 10 quarter_of_grade = enrollment_by_grade[grade] / 4 threshold = threshold > quarter_of_grade ? quarter_of_grade : threshold - memo[grade] = SurveyItem.joins("inner join survey_item_responses on survey_item_responses.survey_item_id = survey_items.id") - .student_survey_items - .where("survey_item_responses.school": school, "survey_item_responses.academic_year": academic_year, "survey_item_responses.grade": grade, "survey_item_responses.survey_item_id": subcategory.survey_items.student_survey_items) - .group("survey_items.id") - .having("count(*) >= #{threshold}") - .count + + si = SurveyItemResponse.student_survey_items_with_sufficient_responses_by_grade(school:, academic_year:, + threshold:) + ssi = @subcategory.survey_items.student_survey_items.map(&:id) + grade_array = Array.new(ssi.length, grade) + + memo[grade] = si.slice(*grade_array.zip(ssi)) end @survey_items_with_sufficient_responses[grade] end diff --git a/app/models/survey_item_response.rb b/app/models/survey_item_response.rb index a6940e27..c8773121 100644 --- a/app/models/survey_item_response.rb +++ b/app/models/survey_item_response.rb @@ -69,4 +69,18 @@ class SurveyItemResponse < ActiveRecord::Base end @teacher_survey_items_with_sufficient_responses[[school, academic_year]] end + + def self.student_survey_items_with_sufficient_responses_by_grade(school:, academic_year:, threshold:) + @student_survey_items_with_sufficient_responses_by_grade ||= Hash.new do |memo, (school, academic_year)| + hash = SurveyItem.joins("inner join survey_item_responses on survey_item_responses.survey_item_id = survey_items.id") + .student_survey_items + .where("survey_item_responses.school": school, "survey_item_responses.academic_year": academic_year) + .group(:grade, :id) + .having("count(*) >= #{threshold}") + .count + memo[[school, academic_year]] = hash + end + + @student_survey_items_with_sufficient_responses_by_grade[[school, academic_year]] + end end