From 9c11882c1133eaf47dd2e7d0e9378a86d39f643c Mon Sep 17 00:00:00 2001 From: Adam Olley Date: Mon, 15 Jul 2024 15:48:54 +0930 Subject: [PATCH] Improve performance of statistics queries Without this, the many sub-queries in stats calculations that JOIN the question_references table dont hit any of the indexes on that table. For sites with large question_references tables - this can be horrible for performance as it ends up doing a seqscan on that table. By adding the usingcontextid field, we instead get indexscan's. --- classes/statistics_calculator.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/classes/statistics_calculator.php b/classes/statistics_calculator.php index c7c27939..82ed872a 100644 --- a/classes/statistics_calculator.php +++ b/classes/statistics_calculator.php @@ -132,6 +132,7 @@ private static function get_attempt_stat_joins($cmid, $groupid, $excluderoles = JOIN {question_references} qr ON qr.itemid = sqq.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid1 JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) @@ -163,6 +164,7 @@ private static function get_attempt_stat_joins($cmid, $groupid, $excluderoles = JOIN {question_references} qr ON qr.itemid = sqq.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid2 JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) @@ -197,6 +199,7 @@ private static function get_attempt_stat_joins($cmid, $groupid, $excluderoles = JOIN {question_references} qr ON qr.itemid = sqq.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid3 JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) @@ -231,6 +234,7 @@ private static function get_attempt_stat_joins($cmid, $groupid, $excluderoles = JOIN {question_references} qr ON qr.itemid = sqq.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid4 JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) @@ -259,6 +263,7 @@ private static function get_attempt_stat_joins($cmid, $groupid, $excluderoles = JOIN {question_references} qr ON qr.itemid = sqq.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid5 JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) @@ -303,6 +308,7 @@ private static function get_attempt_stat_joins($cmid, $groupid, $excluderoles = * @return array */ private static function get_attempt_stat_joins_params($cmid, $quantifiers = null, $userid = null): array { + $contextid = \context_module::instance($cmid)->id; $params = [ 'cmid1' => $cmid, 'cmid2' => $cmid, @@ -311,6 +317,11 @@ private static function get_attempt_stat_joins_params($cmid, $quantifiers = null 'cmid5' => $cmid, 'cmid6' => $cmid, 'cmid7' => $cmid, + 'contextid1' => $contextid, + 'contextid2' => $contextid, + 'contextid3' => $contextid, + 'contextid4' => $contextid, + 'contextid5' => $contextid, 'status1' => question_version_status::QUESTION_STATUS_HIDDEN, 'status2' => question_version_status::QUESTION_STATUS_HIDDEN, 'status3' => question_version_status::QUESTION_STATUS_HIDDEN, @@ -433,6 +444,7 @@ public static function get_question_stats($cmid, $groupid) { JOIN {question_references} qr ON qr.itemid = sqq.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid1 JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) @@ -449,6 +461,7 @@ public static function get_question_stats($cmid, $groupid) { JOIN {question_bank_entries} qbe ON qr.questionbankentryid = qbe.id AND qr.component = 'mod_studentquiz' AND qr.questionarea = 'studentquiz_question' + AND qr.usingcontextid = :contextid2 JOIN {question_versions} qv ON qv.questionbankentryid = qr.questionbankentryid AND qv.version = ( SELECT MAX(version) FROM {question_versions} @@ -464,9 +477,12 @@ public static function get_question_stats($cmid, $groupid) { 'q.parent = 0', 'sq.coursemodule = :cmid1' ]; + $contextid = \context_module::instance($cmid)->id; $params = [ 'cmid1' => $cmid, 'cmid2' => $cmid, + 'contextid1' => $contextid, + 'contextid2' => $contextid, 'status1' => question_version_status::QUESTION_STATUS_HIDDEN, 'status2' => question_version_status::QUESTION_STATUS_HIDDEN, ];