mirror of
https://github.com/moodle/moodle.git
synced 2025-04-18 06:58:08 +02:00
MDL-47426 assign local roles: rewrite query for better performance.
This is an extremely dangerous query, because it includes the user table twice, along-side two other potentially large tables, role_assignments and user_enrolments. The solution is to rewrite the query so that: 1. The subquery is JOINed, not WHERE ... INed. Typically query optimisers handle the JOIN case better. 2. Before the join was role-assignments <-> users <-> subquery. That is, everything was linked to u.id. Now the linking is role-assignments <-> subquery <-> users, so the SELECT DISTINT eu1_u.id FROM {enrolled users} is central. That seems to send a strong hint to the query optimiser about a good order to execute the query.
This commit is contained in:
parent
6597413d41
commit
482ca72089
@ -48,11 +48,12 @@ class core_role_potential_assignees_below_course extends core_role_assign_user_s
|
||||
$fields = 'SELECT ' . $this->required_fields_sql('u');
|
||||
$countfields = 'SELECT COUNT(u.id)';
|
||||
|
||||
$sql = " FROM {user} u
|
||||
LEFT JOIN {role_assignments} ra ON (ra.userid = u.id AND ra.roleid = :roleid AND ra.contextid = :contextid)
|
||||
WHERE u.id IN ($enrolsql)
|
||||
$wherecondition
|
||||
AND ra.id IS NULL";
|
||||
$sql = " FROM ($enrolsql) enrolled_users_view
|
||||
JOIN {user} u ON u.id = enrolled_users_view.id
|
||||
LEFT JOIN {role_assignments} ra ON (ra.userid = enrolled_users_view.id AND
|
||||
ra.roleid = :roleid AND ra.contextid = :contextid)
|
||||
WHERE ra.id IS NULL
|
||||
$wherecondition";
|
||||
$params['contextid'] = $this->context->id;
|
||||
$params['roleid'] = $this->roleid;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user