MDL-30185 question engine reporting: add redundant where to query for perf.

Without this, MySQL fails to cope.
This commit is contained in:
Tim Hunt
2011-11-15 11:00:55 +00:00
parent e25ecdfcf3
commit 471992218f
2 changed files with 44 additions and 27 deletions
+9 -1
View File
@@ -614,13 +614,21 @@ abstract class quiz_attempt_report_table extends table_sql {
return;
}
// This condition roughly filters the list of attempts to be considered.
// It is only used in a subselect to help crappy databases (see MDL-30122)
// therefore, it is better to use a very simple join, which may include
// too many records, than to do a super-accurate join.
$qubaids = new qubaid_join("{quiz_attempts} {$alias}quiza", "{$alias}quiza.uniqueid",
"{$alias}quiza.quiz = :{$alias}quizid", array("{$alias}quizid" => $this->sql->params['quizid']));
$dm = new question_engine_data_mapper();
$inlineview = $dm->question_attempt_latest_state_view($alias);
list($inlineview, $viewparams) = $dm->question_attempt_latest_state_view($alias, $qubaids);
$this->sql->fields .= ",\n$fields";
$this->sql->from .= "\nLEFT JOIN $inlineview ON " .
"$alias.questionusageid = quiza.uniqueid AND $alias.slot = :{$alias}slot";
$this->sql->params[$alias . 'slot'] = $slot;
$this->sql->params = array_merge($this->sql->params, $viewparams);
}
/**
+35 -26
View File
@@ -865,33 +865,42 @@ ORDER BY
END) = 0";
}
public function question_attempt_latest_state_view($alias) {
return "(
SELECT
{$alias}qa.id AS questionattemptid,
{$alias}qa.questionusageid,
{$alias}qa.slot,
{$alias}qa.behaviour,
{$alias}qa.questionid,
{$alias}qa.variant,
{$alias}qa.maxmark,
{$alias}qa.minfraction,
{$alias}qa.flagged,
{$alias}qa.questionsummary,
{$alias}qa.rightanswer,
{$alias}qa.responsesummary,
{$alias}qa.timemodified,
{$alias}qas.id AS attemptstepid,
{$alias}qas.sequencenumber,
{$alias}qas.state,
{$alias}qas.fraction,
{$alias}qas.timecreated,
{$alias}qas.userid
/**
* Get a subquery that returns the latest step of every qa in some qubas.
* Currently, this is only used by the quiz reports. See
* {@link quiz_attempt_report_table::add_latest_state_join()}.
* @param string $alias alias to use for this inline-view.
* @param qubaid_condition $qubaids restriction on which question_usages we
* are interested in. This is important for performance.
* @return array with two elements, the SQL fragment and any params requried.
*/
public function question_attempt_latest_state_view($alias, qubaid_condition $qubaids) {
return array("(
SELECT {$alias}qa.id AS questionattemptid,
{$alias}qa.questionusageid,
{$alias}qa.slot,
{$alias}qa.behaviour,
{$alias}qa.questionid,
{$alias}qa.variant,
{$alias}qa.maxmark,
{$alias}qa.minfraction,
{$alias}qa.flagged,
{$alias}qa.questionsummary,
{$alias}qa.rightanswer,
{$alias}qa.responsesummary,
{$alias}qa.timemodified,
{$alias}qas.id AS attemptstepid,
{$alias}qas.sequencenumber,
{$alias}qas.state,
{$alias}qas.fraction,
{$alias}qas.timecreated,
{$alias}qas.userid
FROM {question_attempts} {$alias}qa
JOIN {question_attempt_steps} {$alias}qas ON
{$alias}qas.id = {$this->latest_step_for_qa_subquery($alias . 'qa.id')}
) $alias";
FROM {$qubaids->from_question_attempts($alias . 'qa')}
JOIN {question_attempt_steps} {$alias}qas ON
{$alias}qas.id = {$this->latest_step_for_qa_subquery($alias . 'qa.id')}
WHERE {$qubaids->where()}
) $alias", $qubaids->from_where_params());
}
protected function latest_step_for_qa_subquery($questionattemptid = 'qa.id') {