Skip to content

Commit 86ddf32

Browse files
floehopperchrislochrisroos
committed
Simplify batching query in PatientStatusUpdater
We've seen some evidence that the batching queries generated by `PatientStatusUpdater#update_programme_statuses!` are (at least sometimes) slow in production, potentially because of a bunch of sequential scans relating to JOINs generated by the call to `ActiveRecord::QueryMethods#includes`. The call to `#includes` is necessary in order to trigger eager loading of associations to avoid N+1 queries when calling `Patient::ProgrammeStatus#assign`. However, this is only relevant for the batch queries which make the model instances available within each batch; not for the batching queries which just work out which model IDs to include in a given batch. Thus we can simplify the batching queries without changing the overall behaviour by using `ActiveRecord::Batches#in_batches` [1] instead of `#find_in_batches` and moving the call to `#includes` onto the batch relation. Note that as per the `ActiveRecord::QueryMethods#includes` docs [2]: > A separate query is performed for each association, unless a join is required > by conditions. This means that the JOINs were only being generated on the batching queries when the patient scope included a condition, e.g. when associated with an `ImmunisationImport`. Given the instance of `PatientStatusUpdaterJob` scheduled overnight [3] uses the default arguments, its batching query is *unscoped* and thus it may not directly benefit from any performance improvements made by the changes in this commit. [1]: https://api.rubyonrails.org/v8.1.3/classes/ActiveRecord/Batches.html#method-i-in_batches [2]: https://api.rubyonrails.org/v8.1.3/classes/ActiveRecord/QueryMethods.html#method-i-includes [3]: https://github.com/NHSDigital/manage-vaccinations-in-schools/blob/6895ee514a018aaa507a460e332a32b3d9e8b6a1/config/sidekiq.yml#L70-L73 Co-authored-by: Chris Lowis <chris.lowis@gofreerange.com> Co-authored-by: Chris Roos <chris.roos@gofreerange.com>
1 parent 9494bf2 commit 86ddf32

1 file changed

Lines changed: 12 additions & 10 deletions

File tree

app/lib/patient_status_updater.rb

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,18 @@ def update_programme_statuses!
4242

4343
merge_patient_scope(Patient::ProgrammeStatus)
4444
.where(academic_year: academic_years)
45-
.includes(
46-
:attendance_record,
47-
:consents,
48-
:patient,
49-
:patient_locations,
50-
:triages,
51-
:vaccination_records,
52-
:parents
53-
)
54-
.find_in_batches do |batch|
45+
.in_batches do |relation|
46+
batch =
47+
relation.includes(
48+
:attendance_record,
49+
:consents,
50+
:patient,
51+
:patient_locations,
52+
:triages,
53+
:vaccination_records,
54+
:parents
55+
).to_a
56+
5557
batch.each(&:assign)
5658

5759
Patient::ProgrammeStatus.import!(

0 commit comments

Comments
 (0)