[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:
@@ -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
|
||||
)""")
|
||||
|
||||
Reference in New Issue
Block a user