Improve database queries for narrowing to personals with another user.

Inspection of the postgres slow queries log showed that the "narrow to
personals with a particular user" database queries were taking a long
time to run (0.5s+).  Further investigation determined that the OR
gate construction used here was causing the entire zephyr_message
table to be scanned; primarily I think because we were using the
implicit constraint that the logged in user had received messages.

This change makes that query explicit (improving performance), while
cleaning up the code to avoid an unnecessary query and read a little
more clearly.

After this change, the relevant database query takes 10s of milliseconds.

(imported from commit 020f5af5846c958386615e37ea9318383bf99ca0)
This commit is contained in:
Tim Abbott 2013-01-03 13:31:58 -05:00
parent 83a0d82d8f
commit 2d94e4c780
1 changed files with 14 additions and 14 deletions

View File

@ -314,23 +314,23 @@ class NarrowBuilder(object):
return Q(recipient=recipient)
else:
# Personal message
try:
recipient_profile = UserProfile.objects.get(user__email=operand)
except UserProfile.DoesNotExist:
raise BadNarrowOperator('unknown user ' + operand)
recipient = Recipient.objects.get(type=Recipient.PERSONAL,
type_id=recipient_profile.id)
self_recipient = Recipient.objects.get(type=Recipient.PERSONAL,
type_id=self.user_profile.id)
if operand == self.user_profile.user.email:
# Personals with self
return Q(recipient__type=Recipient.PERSONAL,
sender__user__email=operand,
recipient=recipient)
else:
# Personals with other user; include both directions.
return (Q(recipient__type=Recipient.PERSONAL) &
(Q(sender__user__email=operand) | Q(recipient=recipient)))
sender=self.user_profile, recipient=self_recipient)
# Personals with other user; include both directions.
try:
narrow_profile = UserProfile.objects.get(user__email=operand)
except UserProfile.DoesNotExist:
raise BadNarrowOperator('unknown user ' + operand)
narrow_recipient = Recipient.objects.get(type=Recipient.PERSONAL,
type_id=narrow_profile.id)
return ((Q(sender=narrow_profile) & Q(recipient=self_recipient)) |
(Q(sender=self.user_profile) & Q(recipient=narrow_recipient)))
def by_search(self, operand):
return (Q(content__icontains=operand) |