[FIX] crm.opportunity.report: query performance

Using a subselect is more efficient than constructing
a complete temporary table of all messages, and then
joining them. This way only messages or relevant
opportunities are used, as most of the time the
report is accessed for a specific subset of opportunities
(by date, salesman, stage, etc.).
The query planner can then use the dedicated index
to quickly access the corresponding messages.

On a sample database with 1 million crm.lead
entries and 10 million mail.message entries
this brings the time for a typical read_group
call on crm.opportunity.report down from 300s to
500ms (600x faster)
This commit is contained in:
Olivier Dony
2016-02-26 18:56:49 +01:00
parent de9342fac4
commit c5b879bfd2
+4 -9
View File
@@ -68,7 +68,9 @@ class crm_opportunity_report(osv.Model):
c.company_id,
c.priority,
c.team_id,
activity.nbr_activities,
(SELECT COUNT(*)
FROM mail_message m
WHERE m.model = 'crm.lead' and m.res_id = c.id) as nbr_activity,
c.active,
c.campaign_id,
c.source_id,
@@ -85,14 +87,7 @@ class crm_opportunity_report(osv.Model):
c.date_conversion as date_conversion
FROM
"crm_lead" c
LEFT JOIN (
SELECT m.res_id, COUNT(*) nbr_activities
FROM "mail_message" m
WHERE m.model = 'crm.lead'
GROUP BY m.res_id ) activity
ON
(activity.res_id = c.id)
LEFT JOIN "crm_stage" stage
ON stage.id = c.stage_id
GROUP BY c.id, activity.nbr_activities, stage.name
GROUP BY c.id, stage.name
)""")