From 41e3b1cdc3e2c7f1070d980de589f5226da4dfe1 Mon Sep 17 00:00:00 2001 From: "Victor Piryns (pivi)" Date: Tue, 19 Mar 2024 17:00:15 +0100 Subject: [PATCH] [PERF] survey: add missing indexes Description: Adding missing indexes to support most of the searches on survey's models to avoid seq.scans and non-selective index scans. Also adding indexes that are inverse to One2many, or dependencies of compute fields (as those if not indexes will trigger a seq.scan when the ORM resolves the dependency tree). If a domain had multiple criteria, only fields with the highest selectivity were indexed. This shall also reduce the amount of tuples returned, reducing IO access and cache trashing. Cardinality: survey_survey -> X (reference quantity) survey_question -> 10X survey_question_answer -> 50X survey_user_input -> 330X survey_user_input_line -> 7200X Reference: task-3724844 closes odoo/odoo#158136 Signed-off-by: Olivier Dony (odo) --- addons/survey/models/survey_question.py | 4 ++-- addons/survey/models/survey_user_input.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/survey/models/survey_question.py b/addons/survey/models/survey_question.py index c1e11f1d7d9..b2dfe4fa5e9 100644 --- a/addons/survey/models/survey_question.py +++ b/addons/survey/models/survey_question.py @@ -705,8 +705,8 @@ class SurveyQuestionAnswer(models.Model): MAX_ANSWER_NAME_LENGTH = 90 # empirically tested in client dropdown # question and question related fields - question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade') - matrix_question_id = fields.Many2one('survey.question', string='Question (as matrix row)', ondelete='cascade') + question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade', index='btree_not_null') + matrix_question_id = fields.Many2one('survey.question', string='Question (as matrix row)', ondelete='cascade', index='btree_not_null') question_type = fields.Selection(related='question_id.question_type') sequence = fields.Integer('Label Sequence order', default=10) scoring_type = fields.Selection(related='question_id.scoring_type') diff --git a/addons/survey/models/survey_user_input.py b/addons/survey/models/survey_user_input.py index 8ca8a4a9ffb..11e252510b9 100644 --- a/addons/survey/models/survey_user_input.py +++ b/addons/survey/models/survey_user_input.py @@ -23,7 +23,7 @@ class SurveyUserInput(models.Model): _inherit = ['mail.thread', 'mail.activity.mixin'] # answer description - survey_id = fields.Many2one('survey.survey', string='Survey', required=True, readonly=True, ondelete='cascade') + survey_id = fields.Many2one('survey.survey', string='Survey', required=True, readonly=True, ondelete='cascade', index=True) scoring_type = fields.Selection(string="Scoring", related="survey_id.scoring_type") start_datetime = fields.Datetime('Start date and time', readonly=True) end_datetime = fields.Datetime('End date and time', readonly=True) @@ -43,7 +43,7 @@ class SurveyUserInput(models.Model): # identification / access access_token = fields.Char('Identification token', default=lambda self: str(uuid.uuid4()), readonly=True, required=True, copy=False) invite_token = fields.Char('Invite token', readonly=True, copy=False) # no unique constraint, as it identifies a pool of attempts - partner_id = fields.Many2one('res.partner', string='Contact', readonly=True) + partner_id = fields.Many2one('res.partner', string='Contact', readonly=True, index='btree_not_null') email = fields.Char('Email', readonly=True) nickname = fields.Char('Nickname', help="Attendee nickname, mainly used to identify them in the survey session leaderboard.") # questions / answers @@ -708,7 +708,7 @@ class SurveyUserInputLine(models.Model): # survey data user_input_id = fields.Many2one('survey.user_input', string='User Input', ondelete='cascade', required=True, index=True) survey_id = fields.Many2one(related='user_input_id.survey_id', string='Survey', store=True, readonly=False) - question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade', required=True) + question_id = fields.Many2one('survey.question', string='Question', ondelete='cascade', required=True, index=True) page_id = fields.Many2one(related='question_id.page_id', string="Section", readonly=False) question_sequence = fields.Integer('Sequence', related='question_id.sequence', store=True) # answer