[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) <odo@odoo.com>
This commit is contained in:
Victor Piryns (pivi)
2024-03-29 12:38:04 +00:00
parent 2f51b84313
commit 41e3b1cdc3
2 changed files with 5 additions and 5 deletions
+2 -2
View File
@@ -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')
+3 -3
View File
@@ -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