[perf] Reduce the number of DB queries in send_message.

For a 4-person stream, we were hitting the DB 8 times, and 4 of
those queries were to lazily get user.email for the 4 recipients
due to upstream code using only().  I added user_profile__email
to the only() call.

I believe this regression started 9/18, and after pushing this
to prod, we would should look at this graph:

https://stats1.zulip.net/graphs/8274cd84588

(imported from commit 70629cb69fe5955c674ba76482609dfe78e5faaf)
This commit is contained in:
Steve Howell
2013-09-23 14:26:00 -04:00
committed by Zev Benjamin
parent 63de50d6f0
commit 50641c3337
2 changed files with 12 additions and 3 deletions

View File

@@ -249,8 +249,17 @@ def do_send_messages(messages):
assert((len(message['recipients']) == 1) or (len(message['recipients']) == 2))
elif (message['message'].recipient.type == Recipient.STREAM or
message['message'].recipient.type == Recipient.HUDDLE):
query = Subscription.objects.select_related("user_profile").only(
"id", "user_profile__id", "user_profile__is_active").filter(
# We use select_related()/only() here, while the PERSONAL case above uses
# get_user_profile_by_id() to get UserProfile objects from cache. Streams will
# typically have more recipients than PMs, so get_user_profile_by_id() would be
# a bit more expensive here, given that we need to hit the DB anyway and only
# care about the email from the user profile.
fields = [
'user_profile__id',
'user_profile__email',
'user_profile__is_active'
]
query = Subscription.objects.select_related("user_profile").only(*fields).filter(
recipient=message['message'].recipient, active=True)
message['recipients'] = [s.user_profile for s in query]
else: