[IMP] mail: better join improve query execution time
- using join on required fields ease PostgreSQL planner guessing - skip useless join, the fastest code is the not executed one - skip dynamic `or` insertion and replace with a union all in CTE - replacing `where exists` with a join is then possible - a bit of alignment from some s to some ms execution time. Submit an "Apply for a job" on website , goes from `"POST /website_form/hr.applicant HTTP/1.0" 200 - 182 2.649 0.106` without this patch, to `"POST /website_form/hr.applicant HTTP/1.0" 200 - 185 0.492 0.107` when this patch is applied closes odoo/odoo#71028 X-original-commit: 783280375ff04955978a14f007f96d6c4d7443b1 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -105,33 +105,39 @@ class Followers(models.Model):
|
||||
query = """
|
||||
SELECT DISTINCT ON (pid) * FROM (
|
||||
WITH sub_followers AS (
|
||||
SELECT fol.id, fol.partner_id, subtype.internal
|
||||
FROM mail_followers fol
|
||||
RIGHT JOIN mail_followers_mail_message_subtype_rel subrel
|
||||
ON subrel.mail_followers_id = fol.id
|
||||
RIGHT JOIN mail_message_subtype subtype
|
||||
ON subtype.id = subrel.mail_message_subtype_id
|
||||
WHERE subrel.mail_message_subtype_id = %%s AND fol.res_model = %%s AND fol.res_id IN %%s
|
||||
SELECT fol.partner_id,
|
||||
coalesce(subtype.internal, false) as internal
|
||||
FROM mail_followers fol
|
||||
JOIN mail_followers_mail_message_subtype_rel subrel ON subrel.mail_followers_id = fol.id
|
||||
JOIN mail_message_subtype subtype ON subtype.id = subrel.mail_message_subtype_id
|
||||
WHERE subrel.mail_message_subtype_id = %s
|
||||
AND fol.res_model = %s
|
||||
AND fol.res_id IN %s
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT id,
|
||||
FALSE
|
||||
FROM res_partner
|
||||
WHERE id=ANY(%s)
|
||||
)
|
||||
SELECT partner.id as pid,
|
||||
partner.active as active, partner.partner_share as pshare,
|
||||
users.notification_type AS notif, array_agg(groups.id) AS groups
|
||||
FROM res_partner partner
|
||||
LEFT JOIN res_users users ON users.partner_id = partner.id AND users.active
|
||||
LEFT JOIN res_groups_users_rel groups_rel ON groups_rel.uid = users.id
|
||||
LEFT JOIN res_groups groups ON groups.id = groups_rel.gid
|
||||
WHERE EXISTS (
|
||||
SELECT partner_id FROM sub_followers
|
||||
WHERE sub_followers.partner_id = partner.id
|
||||
AND (coalesce(sub_followers.internal, false) <> TRUE OR coalesce(partner.partner_share, false) <> TRUE)
|
||||
) %s
|
||||
GROUP BY partner.id, users.notification_type
|
||||
partner.active as active,
|
||||
partner.partner_share as pshare,
|
||||
users.notification_type AS notif,
|
||||
array_agg(groups_rel.gid) AS groups
|
||||
FROM res_partner partner
|
||||
LEFT JOIN res_users users ON users.partner_id = partner.id
|
||||
AND users.active
|
||||
LEFT JOIN res_groups_users_rel groups_rel ON groups_rel.uid = users.id
|
||||
JOIN sub_followers ON sub_followers.partner_id = partner.id
|
||||
AND NOT (sub_followers.internal AND partner.partner_share)
|
||||
GROUP BY partner.id,
|
||||
users.notification_type
|
||||
) AS x
|
||||
ORDER BY pid, notif
|
||||
""" % ('OR partner.id IN %s' if pids else '')
|
||||
params = [subtype_id, records._name, tuple(records.ids)]
|
||||
if pids:
|
||||
params.append(tuple(pids))
|
||||
"""
|
||||
params = [subtype_id, records._name, tuple(records.ids), list(pids) or []]
|
||||
self.env.cr.execute(query, tuple(params))
|
||||
res = self.env.cr.fetchall()
|
||||
elif pids:
|
||||
|
||||
Reference in New Issue
Block a user