Skip to content

Commit 9dffd17

Browse files
committed
[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.
1 parent 105b1c0 commit 9dffd17

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

addons/website_forum/models/res_users.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,24 @@ def __init__(self, pool, cr):
3030
def _get_user_badge_level(self):
3131
""" Return total badge per level of users
3232
TDE CLEANME: shouldn't check type is forum ? """
33-
badge_groups = self.env['gamification.badge.user'].read_group(
34-
[('level', 'in', ['gold', 'silver', 'bronze'])],
35-
['user_id', 'level', 'badge_id'],
36-
['user_id', 'level'],
37-
lazy=False)
38-
badge_data = dict()
39-
for group in badge_groups:
40-
badge_data.setdefault(group['user_id'][0], dict())[group['level']] = group['__count']
4133
for user in self:
42-
user.gold_badge = badge_data.get(user.id) and badge_data[user.id].get('gold', 0) or 0
43-
user.silver_badge = badge_data.get(user.id) and badge_data[user.id].get('silver', 0) or 0
44-
user.bronze_badge = badge_data.get(user.id) and badge_data[user.id].get('bronze', 0) or 0
34+
user.gold_badge = 0
35+
user.silver_badge = 0
36+
user.bronze_badge = 0
37+
38+
self.env.cr.execute("""
39+
SELECT bu.user_id, b.level, count(1)
40+
FROM gamification_badge_user bu, gamification_badge b
41+
WHERE bu.user_id IN %s
42+
AND bu.badge_id = b.id
43+
AND b.level IS NOT NULL
44+
GROUP BY bu.user_id, b.level
45+
ORDER BY bu.user_id;
46+
""", [tuple(self.ids)])
47+
48+
for (user_id, level, count) in self.env.cr.fetchall():
49+
# levels are gold, silver, bronze but fields have _badge postfix
50+
self.browse(user_id)['{}_badge'.format(level)] = count
4551

4652
@api.model
4753
def _generate_forum_token(self, user_id, email):

0 commit comments

Comments
 (0)