Permalink
Browse files

MDL-29520 question engine: work-around bad MySQL delete performance.

This is a temporary fix, until the new API from MDL-29589 is available.

(amended to fix comments)
  • Loading branch information...
1 parent 74969d8 commit ae3056cb006666aa78332e3941545264acc9fa24 @timhunt timhunt committed with stronk7 Sep 30, 2011
Showing with 44 additions and 0 deletions.
  1. +44 −0 question/engine/datalib.php
View
44 question/engine/datalib.php
@@ -659,6 +659,11 @@ public function delete_questions_usage_by_activities(qubaid_condition $qubaids)
WHERE $where)", $params);
}
+ if ($this->db->get_dbfamily() == 'mysql') {
+ $this->delete_usage_records_for_mysql($qubaids);
+ return;
+ }
+
$this->db->delete_records_select('question_attempt_step_data', "attemptstepid IN (
SELECT qas.id
FROM {question_attempts} qa
@@ -679,6 +684,40 @@ public function delete_questions_usage_by_activities(qubaid_condition $qubaids)
}
/**
+ * This function is a work-around for poor MySQL performance with
+ * DELETE FROM x WHERE id IN (SELECT ...). We have to use a non-standard
+ * syntax to get good performance. See MDL-29520.
+ * @param qubaid_condition $qubaids identifies which question useages to delete.
+ */
+ protected function delete_usage_records_for_mysql(qubaid_condition $qubaids) {
+ // TODO once MDL-29589 is fixed, eliminate this method, and instead use the new $DB API.
+ $this->db->execute('
+ DELETE qu, qa, qas, qasd
+ FROM {question_usages} qu
+ JOIN {question_attempts} qa ON qa.questionusageid = qu.id
+ JOIN {question_attempt_steps} qas ON qas.questionattemptid = qa.id
+ JOIN {question_attempt_step_data} qasd ON qasd.attemptstepid = qas.id
+ WHERE qu.id ' . $qubaids->usage_id_in(),
+ $qubaids->usage_id_in_params());
+ }
+
+ /**
+ * This function is a work-around for poor MySQL performance with
+ * DELETE FROM x WHERE id IN (SELECT ...). We have to use a non-standard
+ * syntax to get good performance. See MDL-29520.
+ * @param string $test sql fragment.
+ * @param array $params used by $test.
+ */
+ protected function delete_attempt_steps_for_mysql($test, $params) {
+ // TODO once MDL-29589 is fixed, eliminate this method, and instead use the new $DB API.
+ $this->db->execute('
+ DELETE qas, qasd
+ FROM {question_attempt_steps} qas
+ JOIN {question_attempt_step_data} qasd ON qasd.attemptstepid = qas.id
+ WHERE qas.questionattemptid ' . $test, $params);
+ }
+
+ /**
* Delete all the steps for a question attempt.
* @param int $qaids question_attempt id.
*/
@@ -693,6 +732,11 @@ public function delete_steps_for_question_attempts($qaids, $context) {
FROM {question_attempt_steps}
WHERE questionattemptid $test)", $params);
+ if ($this->db->get_dbfamily() == 'mysql') {
+ $this->delete_attempt_steps_for_mysql($test, $params);
+ return;
+ }
+
$this->db->delete_records_select('question_attempt_step_data', "attemptstepid IN (
SELECT qas.id
FROM {question_attempt_steps} qas

0 comments on commit ae3056c

Please sign in to comment.