From 30b96929151073bcd7c6970b538cec404391da1a Mon Sep 17 00:00:00 2001 From: Alan Zarembok Date: Thu, 25 Apr 2019 08:55:59 -0400 Subject: [PATCH] PROD-9: Fix badly performing database query for bulk email by using the union() function to combine multiple querysets together, rather than the or (|) operator. This avoids a very inefficient OUTER JOIN query that reads the entire user table. --- lms/djangoapps/bulk_email/tasks.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lms/djangoapps/bulk_email/tasks.py b/lms/djangoapps/bulk_email/tasks.py index 08beb958d0..0a3aa092e4 100644 --- a/lms/djangoapps/bulk_email/tasks.py +++ b/lms/djangoapps/bulk_email/tasks.py @@ -179,10 +179,10 @@ def perform_delegate_email_batches(entry_id, course_id, task_input, action_name) target.get_users(course_id, user_id) for target in targets ] - combined_set = User.objects.none() - for qset in recipient_qsets: - combined_set |= qset - combined_set = combined_set.distinct() + # Use union here to combine the qsets instead of the | operator. This avoids generating an + # inefficient OUTER JOIN query that would read the whole user table. + combined_set = recipient_qsets[0].union(*recipient_qsets[1:]) if len(recipient_qsets) > 1 \ + else recipient_qsets[0] recipient_fields = ['profile__name', 'email'] log.info(u"Task %s: Preparing to queue subtasks for sending emails for course %s, email %s",