-
Bug
-
Resolution: Fixed
-
Minor
-
3.8.5
-
MOODLE_38_STABLE
-
MOODLE_38_STABLE, MOODLE_39_STABLE
-
MDL-69687-master -
The query used to delete course module completion data from a course is inefficient.
The current query which can be found within the remove_course_contents function in /lib/moodlelib.php at lines 5327-5329 relies upon a subquery:
DELETE FROM mdl_course_modules_completion WHERE coursemoduleid IN (SELECT id FROM mdl_course_modules WHERE course=?)
The subquery approach is handy as it works across data engines but is very inefficient. An explain plan on MySQL show the query requiring a full table scan on mdl_course_modules_completion. On a database with about 2.1 million records in the mdl_course_modules_completion table, the delete statement frequently takes over 60 seconds to run.
By comparison using a join allows the query to use indexes on both database tables, mdl_courmodu_cou_ix and mdl_courmoducomp_cou_ix.
DELETE cmc
FROM mdl_course_modules_completion cmc
INNER JOIN mdl_course_modules cm ON cm.id = cmc.coursemoduleid
WHERE cm.course = 180;
I believe the above syntax would also be valid on Microsoft SQL Server. PostgreSQL would require different syntax:
DELETE from mdl_course_modules_completion cmc
USING mdl_course_modules cm
WHERE cm.id = cmc.coursemoduleid
AND cm.course = ?
I am less familiar with PostgreSQL to say if this approach is any better there. On a very small test database, I get the same explain plan with the above query as with the original version with the subquery.