From 9c7e18030e0e95b0b89a12e01676000145a7b77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Wed, 8 Dec 2021 12:24:00 +0000 Subject: [PATCH] [FIX] mail: improve performance of channel member_count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forcing a fetch of all channel partners for all channels is not efficient because there are too many of them. Replace by a count done in SQL through `read_group`. Time goes from 100ms to 3ms for 1000s of members in 100s of channels. Part of task-2702450 closes odoo/odoo#81175 X-original-commit: 7c77775a84474ccdfe32bdd783291728fbfbdc42 Signed-off-by: Sébastien Theys (seb) --- addons/mail/models/mail_channel.py | 6 ++++-- addons/test_discuss_full/tests/test_performance.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 5cee4c43ac2..bf404de2a7c 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -73,7 +73,7 @@ class Channel(models.Model): groups='base.group_user') rtc_session_ids = fields.One2many('mail.channel.rtc.session', 'channel_id', groups="base.group_system") is_member = fields.Boolean('Is Member', compute='_compute_is_member', compute_sudo=True) - member_count = fields.Integer(string="Member Count", compute='_compute_member_count', help="Excluding guests from count.") + member_count = fields.Integer(string="Member Count", compute='_compute_member_count', compute_sudo=True, help="Excluding guests from count.") group_ids = fields.Many2many( 'res.groups', string='Auto Subscription', help="Members of those groups will automatically added as followers. " @@ -154,8 +154,10 @@ class Channel(models.Model): @api.depends('channel_partner_ids') def _compute_member_count(self): + read_group_res = self.env['mail.channel.partner'].read_group(domain=[('channel_id', 'in', self.ids)], fields=['channel_id'], groupby=['channel_id']) + member_count_by_channel_id = {item['channel_id'][0]: item['channel_id_count'] for item in read_group_res} for channel in self: - channel.member_count = len(channel.with_context(active_test=False).channel_partner_ids) + channel.member_count = member_count_by_channel_id.get(channel.id, 0) # ONCHANGE diff --git a/addons/test_discuss_full/tests/test_performance.py b/addons/test_discuss_full/tests/test_performance.py index f09fb62d1bc..3fe64c7e53c 100644 --- a/addons/test_discuss_full/tests/test_performance.py +++ b/addons/test_discuss_full/tests/test_performance.py @@ -99,7 +99,7 @@ class TestDiscussFullPerformance(TransactionCase): self.maxDiff = None self.users[0].flush() self.users[0].invalidate_cache() - with self.assertQueryCount(emp=90): + with self.assertQueryCount(emp=91): init_messaging = self.users[0].with_user(self.users[0])._init_messaging() self.assertEqual(init_messaging, {