Quiz question completion

Re: Quiz question completion

- Tim Hunt の投稿
返信数: 3
画像 Core developers 画像 Documentation writers 画像 Particularly helpful Moodlers 画像 Peer reviewers 画像 Plugin developers

I think question_engine_data_mapper::load_questions_usages_latest_steps() is the method you are looking for.

https://github.com/moodle/moodle/blob/master/question/engine/datalib.php#L554


Tim Hunt への返信

Re: Quiz question completion

- Michael Ko の投稿

Thanks again Tim for your fantastic suggestion.

It reduced the process of determining a quiz's completion from 500ms to 60ms for a 134 question quiz.

Unfortunately, this 60ms is still too much (given these progress bars are on a landing page with a list of up to 30 quizzes), so I've had to go against best practices and directly execute a slightly modified version of the query triggered by: 

question_engine_data_mapper::load_questions_usages_latest_steps()

As follows:

$sql = "SELECT COUNT(*)
FROM {question_attempts} qa
JOIN {question_attempt_steps} qas
ON qas.questionattemptid = qa.id
AND qas.sequencenumber = (SELECT MAX(sequencenumber) FROM {question_attempt_steps} WHERE questionattemptid = qa.id)
WHERE qa.questionusageid = ?
AND state = ?";
$num_answered = $DB->count_records_sql($sql, array($question_usage_id, 'complete'));
This query takes approx 13-25ms to execute.

Thanks again

Michael Ko への返信

Re: Quiz question completion

- Michael Ko の投稿

In fact hard coding 

AND qas.sequencenumber = (SELECT MAX(sequencenumber) FROM {question_attempt_steps} WHERE questionattemptid = qa.id)

to AND qas.sequencenumber = 1

reduces the time to 1ms

Michael Ko への返信

Re: Quiz question completion

- Tim Hunt の投稿
画像 Core developers 画像 Documentation writers 画像 Particularly helpful Moodlers 画像 Peer reviewers 画像 Plugin developers

Well, replacing the whole query with

SELECT 1

would be even faster still. There is no point speeding up the query by changing it to give the wrong answer.

Your fundamental problem is doing one DB query for each quiz attempt. You should be trying to load all the data for all attempts in one query, and you can, using the method I suggested, if you understand the qubaid_condition part of the API.