-
Ivan Yelizariev authored
This commit fixes the performance issue in getting statistics for ``activity_state`` (colored clock icon for overdue/today/planned) in CRM. The query has been tested for several years on a large database (Odoo's own production database). Performance test on 29 K crm.lead records (activity_state): With a filter for 10 records: ``` | measurement | before | after | |--------------------+--------+-------| | number of queries | 25 | 5 | | query time, ms | 12 | 95 | (*) | remaining time, ms | 32 | 7 | ``` All records: ``` | measurement | before | after | |--------------------+--------+-------| | number of queries | 1326 | 5 | | query time, ms | 1739 | 129 | | remaining time, ms | 47934 | 17 | ``` As we can see in the last results, the time went from almost 50 seconds (not responsive at all) to 150 milliseconds (responsive). The time increase in (*) may be caused by imperfect measurements, which are raw and not averaged measures. --- opw-2346901 task-1915411 closes odoo/odoo#67004 Signed-off-by:
Raphael Collet (rco) <rco@openerp.com> Co-authored-by:
Nicolas Seinlet <nse@odoo.com>
Ivan Yelizariev authoredThis commit fixes the performance issue in getting statistics for ``activity_state`` (colored clock icon for overdue/today/planned) in CRM. The query has been tested for several years on a large database (Odoo's own production database). Performance test on 29 K crm.lead records (activity_state): With a filter for 10 records: ``` | measurement | before | after | |--------------------+--------+-------| | number of queries | 25 | 5 | | query time, ms | 12 | 95 | (*) | remaining time, ms | 32 | 7 | ``` All records: ``` | measurement | before | after | |--------------------+--------+-------| | number of queries | 1326 | 5 | | query time, ms | 1739 | 129 | | remaining time, ms | 47934 | 17 | ``` As we can see in the last results, the time went from almost 50 seconds (not responsive at all) to 150 milliseconds (responsive). The time increase in (*) may be caused by imperfect measurements, which are raw and not averaged measures. --- opw-2346901 task-1915411 closes odoo/odoo#67004 Signed-off-by:
Raphael Collet (rco) <rco@openerp.com> Co-authored-by:
Nicolas Seinlet <nse@odoo.com>
test_mail_models.py 4.52 KiB
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class MailTestSimple(models.Model):
""" A very simple model only inheriting from mail.thread when only
communication history is necessary. """
_description = 'Simple Chatter Model'
_name = 'mail.test.simple'
_inherit = ['mail.thread']
name = fields.Char()
email_from = fields.Char()
class MailTestStandard(models.Model):
""" This model can be used in tests when automatic subscription and simple
tracking is necessary. Most features are present in a simple way. """
_description = 'Standard Chatter Model'
_name = 'mail.test.track'
_inherit = ['mail.thread']
name = fields.Char()
email_from = fields.Char()
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange')
umbrella_id = fields.Many2one('mail.test', track_visibility='onchange')
company_id = fields.Many2one('res.company')
class MailTestActivity(models.Model):
""" This model can be used to test activities in addition to simple chatter
features. """
_description = 'Activity Model'
_name = 'mail.test.activity'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Char()
date = fields.Date()
email_from = fields.Char()
active = fields.Boolean(default=True)
def action_start(self, action_summary):
return self.activity_schedule(
'test_mail.mail_act_test_todo',
summary=action_summary
)
def action_close(self, action_feedback):
self.activity_feedback(['test_mail.mail_act_test_todo'], feedback=action_feedback)
class MailTestFull(models.Model):
""" This model can be used in tests when complex chatter features are
required like modeling tasks or tickets. """
_description = 'Full Chatter Model'
_name = 'mail.test.full'
_inherit = ['mail.thread']
name = fields.Char()
email_from = fields.Char(track_visibility='always')
count = fields.Integer(default=1)
datetime = fields.Datetime(default=fields.Datetime.now)
mail_template = fields.Many2one('mail.template', 'Template')
customer_id = fields.Many2one('res.partner', 'Customer', track_visibility='onchange', track_sequence=2)
user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', track_sequence=1)
umbrella_id = fields.Many2one('mail.test', track_visibility='onchange')
def _track_template(self, tracking):
res = super(MailTestFull, self)._track_template(tracking)
record = self[0]
changes, tracking_value_ids = tracking[record.id]
if 'customer_id' in changes and record.mail_template:
res['customer_id'] = (record.mail_template, {'composition_mode': 'mass_mail'})
elif 'datetime' in changes:
res['datetime'] = ('test_mail.mail_test_full_tracking_view', {'composition_mode': 'mass_mail'})
return res
def _track_subtype(self, init_values):
self.ensure_one()
if 'umbrella_id' in init_values and self.umbrella_id:
return 'test_mail.st_mail_test_full_umbrella_upd'
return super(MailTestFull, self)._track_subtype(init_values)
class MailTestAlias(models.Model):
""" This model can be used in tests when umbrella records like projects
or teams are required. """
_description = 'Alias Chatter Model'
_name = 'mail.test'
_mail_post_access = 'read'
_inherit = ['mail.thread', 'mail.alias.mixin']
name = fields.Char()
description = fields.Text()
customer_id = fields.Many2one('res.partner', 'Customer')
alias_id = fields.Many2one(
'mail.alias', 'Alias',
delegate=True)
def get_alias_model_name(self, vals):
return vals.get('alias_model', 'mail.test')
def get_alias_values(self):
self.ensure_one()
res = super(MailTestAlias, self).get_alias_values()
res['alias_force_thread_id'] = self.id
res['alias_parent_thread_id'] = self.id
return res
class MailModel(models.Model):
_name = 'test_performance.mail'
_description = 'Test Performance Mail'
_inherit = 'mail.thread'
name = fields.Char()
value = fields.Integer()
value_pc = fields.Float(compute="_value_pc", store=True)
track = fields.Char(default='test', track_visibility="onchange")
partner_id = fields.Many2one('res.partner', string='Customer')
@api.depends('value')
def _value_pc(self):
for record in self:
record.value_pc = float(record.value) / 100