Tornado: Fill the Tornado UserMessage cache using manual query.

The actual database query that we use to fill the UserMessage cache
only takes a few hundred milliseconds to run; however the process of
iterating through the results would take 3-5 seconds because the
Django ORM is not very efficient for small tables where we're only
interested in the integer values in a couple columns.

So we can save most of that Tornado startup time by just doing this
one query manually; I left the original query next to it in a comment
so it is easy to keep it all up to date as we change our product.

(imported from commit ac4675bcdda5d812ebfbe211450c85ee2787ee66)
This commit is contained in:
Tim Abbott
2013-03-25 14:21:53 -04:00
parent 2aae6190d2
commit 1df99937a9

View File

@@ -13,6 +13,7 @@ import requests
import simplejson
import subprocess
import collections
from django.db import connection
class Callbacks(object):
# A user received a message. The key is user_profile.id.
@@ -92,8 +93,19 @@ def initialize_user_messages():
except Message.DoesNotExist:
cache_minimum_id = 1
for um in UserMessage.objects.filter(message_id__gte=cache_minimum_id).order_by("message"):
add_user_message(um.user_profile_id, um.message_id)
# These next few lines implement the following Django ORM
# algorithm using raw SQL:
## for um in UserMessage.objects.filter(message_id__gte=cache_minimum_id).order_by("message"):
## add_user_message(um.user_profile_id, um.message_id)
# We do this because marshalling the Django objects is very
# inefficient; total time consumed with the raw SQL is about
# 600ms, vs. 3000ms-5000ms if we go through the ORM.
cursor = connection.cursor()
cursor.execute("SELECT user_profile_id, message_id from zephyr_usermessage " +
"where message_id >= %s order by message_id", [cache_minimum_id])
for row in cursor.fetchall():
(user_profile_id, message_id) = row
add_user_message(user_profile_id, message_id)
streams = {}
for stream in Stream.objects.select_related().all():