comparison gpp/forums/feeds.py @ 387:b15726767ab8

Fixing #191; terrible performance on the combined forums RSS feed query. Use an .extra() clause to force the WHERE on a query to use the primary key.
author Brian Neal <bgneal@gmail.com>
date Sat, 19 Mar 2011 01:52:41 +0000
parents 2a03c69792d8
children c3231af55778
comparison
equal deleted inserted replaced
386:9fcd366f22dc 387:b15726767ab8
18 18
19 def get_object(self, request, forum_slug): 19 def get_object(self, request, forum_slug):
20 # only return public forums 20 # only return public forums
21 if forum_slug: 21 if forum_slug:
22 forum = get_object_or_404(Forum, slug=forum_slug) 22 forum = get_object_or_404(Forum, slug=forum_slug)
23 if forum.category.groups.count() > 0: 23 if forum.id not in Forum.objects.public_forum_ids():
24 raise ObjectDoesNotExist 24 raise ObjectDoesNotExist
25 return forum 25 return forum
26 26
27 else: 27 else:
28 # return None to indicate we want a combined feed 28 # return None to indicate we want a combined feed
53 return copyright_str() 53 return copyright_str()
54 54
55 def items(self, obj): 55 def items(self, obj):
56 if obj is None: 56 if obj is None:
57 # return a combined feed of public forum threads 57 # return a combined feed of public forum threads
58 items = Post.objects.filter( 58 #
59 topic__forum__in=Forum.objects.public_forums()) 59 # This didn't work real well on InnoDb:
60 # items = Post.objects.filter(
61 # topic__forum__in=Forum.objects.public_forums())
62 #
63 # The where clause in the generated SQL looked like this:
64 # WHERE `forums_topic`.`forum_id` IN ( ... )
65 # This was terrible for performance. This does much better:
66 # WHERE `forums_topic`.`id` IN ( ... )
67 #
68 # So we use Django's .extra() to force the above.
69
70 public_forum_ids = Forum.objects.public_forum_ids()
71 ids = ','.join(str(pub) for pub in public_forum_ids)
72
73 items = Post.objects.extra(
74 where=['forums_topic.id in (%s)' % ids])
75
60 else: 76 else:
61 items = Post.objects.filter(topic__forum__id=obj.id) 77 items = Post.objects.filter(topic__forum__id=obj.id)
62 return items.order_by('-creation_date').select_related()[:30] 78 return items.order_by('-creation_date').select_related(depth=2)[:30]
63 79
64 def item_title(self, item): 80 def item_title(self, item):
65 return item.topic.name 81 return item.topic.name
66 82
67 def item_description(self, item): 83 def item_description(self, item):