[FIX] mass_mailing: fix slow contact number query

The query was computing the count for all mailing lists, not just the
one being requested. This prevents optimizing the SELECT with indexes.
In addition, using a subselect for the blacklist forced a full table
scan on the contacts - switching to a LEFT JOIN avoids that.

With a blacklist of a few hundred thousand entries, and a table of
mailing list contacts in the same order of magnitude, this brings the
SELECT from 3+ seconds down to 3 milliseconds - with the same result.

Bonus: no need to perform the regexp extraction of emails to test for
NULL values -> substring(x) is NULL iff x is NULL.
This commit is contained in:
Olivier Dony
2018-11-16 16:35:22 +01:00
parent a103d4a43e
commit 8545e05fc0
+6 -4
View File
@@ -114,14 +114,16 @@ class MassMailingList(models.Model):
from
mail_mass_mailing_contact_list_rel r
left join mail_mass_mailing_contact c on (r.contact_id=c.id)
left join mail_blacklist bl on (LOWER(substring(c.email, %s)) = bl.email and bl.active)
where
list_id in %s
COALESCE(r.opt_out,FALSE) = FALSE
AND substring(c.email, '%s') IS NOT NULL
AND LOWER(substring(c.email, '%s')) NOT IN (select email from mail_blacklist where active = TRUE)
AND c.email IS NOT NULL
AND bl.id IS NULL
group by
list_id
''' % (EMAIL_PATTERN, EMAIL_PATTERN))
data = dict(self.env.cr.fetchall())
''')
data = dict(self.env.cr.fetchall(), [EMAIL_PATTERN, tuple(self.ids)])
for mailing_list in self:
mailing_list.contact_nbr = data.get(mailing_list.id, 0)