From e75ea7db535bf8b46dd2ca95742391599510817e Mon Sep 17 00:00:00 2001 From: std-odoo Date: Mon, 6 Feb 2023 06:45:33 +0000 Subject: [PATCH] [FIX] mail: for the complexity of the mail message unlink method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug === When we remove some mail messages, we invalidate the cache of the related documents. But in the same loop we call _invalidate_documents which invalidate the cache, and so at the next iteration we will need to make a new SQL query to know if the message is a "thread message". So because of the prefetch ids, and because we invalidate in the loop, if we unlink 1000 message, we will make 1000 SQL queries to fetch the fields values of the 1000 messages. Note that the unlink method will invalidate the entire cache anyway, so unlike the write / create methods, we shouldn't need to invalidate manually the related documents. Task-3171093 closes odoo/odoo#112494 X-original-commit: f8958e9bbd4c7c37f614b20f7ed4d4825d438362 Signed-off-by: Warnon Aurélien (awa) Signed-off-by: Stéphane Debauche (std) --- addons/mail/models/mail_message.py | 4 ++-- addons/test_mass_mailing/tests/test_performance.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 4ef8133eaef..e584d1ee3b3 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -663,6 +663,8 @@ class Message(models.Model): def unlink(self): # cascade-delete attachments that are directly attached to the message (should only happen # for mail.messages that act as parent for a standalone mail.mail record). + # the cache of the related document doesn't need to be invalidate (see @_invalidate_documents) + # because the unlink method invalidates the whole cache anyway if not self: return True self.check_access_rule('unlink') @@ -674,8 +676,6 @@ class Message(models.Model): for elem in self: for partner in elem.partner_ids & partners_with_user: messages_by_partner[partner] |= elem - if elem.is_thread_message(): - elem._invalidate_documents() # Notify front-end of messages deletion for partners having a user if messages_by_partner: diff --git a/addons/test_mass_mailing/tests/test_performance.py b/addons/test_mass_mailing/tests/test_performance.py index cb1e5c9b8ae..70dec0d4677 100644 --- a/addons/test_mass_mailing/tests/test_performance.py +++ b/addons/test_mass_mailing/tests/test_performance.py @@ -54,7 +54,7 @@ class TestMassMailPerformance(TestMassMailPerformanceBase): self.assertEqual(mailing.delivered, 50) # runbot needs +3 compared to local - with self.assertQueryCount(__system__=68, marketing=67): # tm 66/66 + with self.assertQueryCount(__system__=18, marketing=17): # tm 15/15 self.env['mail.mail'].sudo().search([('to_delete', '=', True)]).unlink() mails = self.env['mail.mail'].sudo().search([('mailing_id', '=', mailing.id)]) @@ -101,7 +101,7 @@ class TestMassMailBlPerformance(TestMassMailPerformanceBase): self.assertEqual(mailing.delivered, 50) # runbot needs +3 compared to local - with self.assertQueryCount(__system__=68, marketing=67): # tm 66/66 + with self.assertQueryCount(__system__=18, marketing=17): # tm 15/15 self.env['mail.mail'].sudo().search([('to_delete', '=', True)]).unlink() cancelled_mail_count = self.env['mail.mail'].sudo().search([('mailing_id', '=', mailing.id)])