Mercurial > public > sg101
changeset 393:9af6bd45c1f8
Another try at #191 after getting some good advice in a django-users thread.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 24 Mar 2011 00:15:34 +0000 |
parents | 79240675b903 |
children | 2cb0cc334c50 |
files | gpp/forums/feeds.py gpp/forums/models.py |
diffstat | 2 files changed, 16 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/gpp/forums/feeds.py Wed Mar 23 02:02:44 2011 +0000 +++ b/gpp/forums/feeds.py Thu Mar 24 00:15:34 2011 +0000 @@ -4,8 +4,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import get_object_or_404 -from forums.models import Forum -from forums.models import Post +from forums.models import Forum, Topic, Post from core.functions import copyright_str @@ -55,27 +54,24 @@ def items(self, obj): if obj is None: # return a combined feed of public forum threads - # - # This didn't work real well on InnoDb: - # items = Post.objects.filter( - # topic__forum__in=Forum.objects.public_forums()) - # - # For some reason, MySQL wasn't using an index when "in" was used. - # So let's do this the hard way as a work-around: - public_forum_ids = Forum.objects.public_forum_ids() - posts = [] - for forum_id in public_forum_ids: - posts.extend(list(Post.objects.filter( - topic__forum=forum_id).order_by('-creation_date').select_related( - 'topic', 'user', 'topic__forum')[:30])) + # This was tricky to do without suffering a large performance + # impact. Because the number of forums is small, MySQL did not + # try to use an index and ended up searching all the topics for + # candidate posts. We work around this first getting a small list + # of candidate topics, and then searching them. This is more + # queries but a *lot* more time efficient. - posts.sort(key=lambda x: x.creation_date, reverse=True) - return posts[:30] + forum_ids = Forum.objects.public_forum_ids() + topic_ids = list(Topic.objects.filter(forum__in=forum_ids).order_by( + '-update_date').values_list('id', flat=True)[:30]) + items = Post.objects.filter(topic__in=topic_ids) else: - return Post.objects.filter(topic__forum__id=obj.id).order_by( - '-creation_date').select_related('topic', 'user', 'topic__forum')[:30] + items = Post.objects.filter(topic__forum=obj) + + return items.order_by('-creation_date').select_related('topic', 'user', + 'topic__forum')[:30] def item_title(self, item): return item.topic.name
--- a/gpp/forums/models.py Wed Mar 23 02:02:44 2011 +0000 +++ b/gpp/forums/models.py Thu Mar 24 00:15:34 2011 +0000 @@ -202,7 +202,7 @@ # denormalized fields to reduce database hits post_count = models.IntegerField(blank=True, default=0) - update_date = models.DateTimeField() + update_date = models.DateTimeField(db_index=True) last_post = models.OneToOneField('Post', blank=True, null=True, related_name='parent_topic')