[IMP] website_forum: users page performances

The read_group collating user badge counts is extremely slow when
there's a large number of users (possibly even slower than 8.0's naive
approach), replace the whole thing by a single SQL query seems to yield
pretty significant (~2 orders of magnitude) performance improvements on
the computing function resulting in ~1 order of magnitude improvement
for the page as a whole.
This commit is contained in:
Xavier Morel
2015-10-06 10:33:11 +02:00
parent 105b1c0014
commit 9dffd17bd5
+17 -11
View File
@@ -30,18 +30,24 @@ class Users(models.Model):
def _get_user_badge_level(self):
""" Return total badge per level of users
TDE CLEANME: shouldn't check type is forum ? """
badge_groups = self.env['gamification.badge.user'].read_group(
[('level', 'in', ['gold', 'silver', 'bronze'])],
['user_id', 'level', 'badge_id'],
['user_id', 'level'],
lazy=False)
badge_data = dict()
for group in badge_groups:
badge_data.setdefault(group['user_id'][0], dict())[group['level']] = group['__count']
for user in self:
user.gold_badge = badge_data.get(user.id) and badge_data[user.id].get('gold', 0) or 0
user.silver_badge = badge_data.get(user.id) and badge_data[user.id].get('silver', 0) or 0
user.bronze_badge = badge_data.get(user.id) and badge_data[user.id].get('bronze', 0) or 0
user.gold_badge = 0
user.silver_badge = 0
user.bronze_badge = 0
self.env.cr.execute("""
SELECT bu.user_id, b.level, count(1)
FROM gamification_badge_user bu, gamification_badge b
WHERE bu.user_id IN %s
AND bu.badge_id = b.id
AND b.level IS NOT NULL
GROUP BY bu.user_id, b.level
ORDER BY bu.user_id;
""", [tuple(self.ids)])
for (user_id, level, count) in self.env.cr.fetchall():
# levels are gold, silver, bronze but fields have _badge postfix
self.browse(user_id)['{}_badge'.format(level)] = count
@api.model
def _generate_forum_token(self, user_id, email):