MDL-68183 auth: Fix the performance of get_complete_user_data search
When searching for the user by a case-insensitive field (email address is the only one supported now), the performance may be very poor as the DB cannot use the index due to the LOWER() operation and the full sequential scan of all the user records is performed. On some DBs such as MySQL, this can be significantly improved by pre-filtering the users with accent-insensitive search. So we first perform accent-insensitive search for potential candidates in a subselect, which can use the index. Only then we perform the additional accent-sensitive search on this limited set or records.
This commit is contained in:
+9
-1
@@ -4846,11 +4846,15 @@ function get_complete_user_data($field, $value, $mnethostid = null, $throwexcept
|
||||
// Build the WHERE clause for an SQL query.
|
||||
$params = array('fieldval' => $value);
|
||||
|
||||
// Do a case-insensitive query, if necessary.
|
||||
// Do a case-insensitive query, if necessary. These are generally very expensive. The performance can be improved on some DBs
|
||||
// such as MySQL by pre-filtering users with accent-insensitive subselect.
|
||||
if (in_array($field, $caseinsensitivefields)) {
|
||||
$fieldselect = $DB->sql_equal($field, ':fieldval', false);
|
||||
$idsubselect = $DB->sql_equal($field, ':fieldval2', false, false);
|
||||
$params['fieldval2'] = $value;
|
||||
} else {
|
||||
$fieldselect = "$field = :fieldval";
|
||||
$idsubselect = '';
|
||||
}
|
||||
$constraints = "$fieldselect AND deleted <> 1";
|
||||
|
||||
@@ -4867,6 +4871,10 @@ function get_complete_user_data($field, $value, $mnethostid = null, $throwexcept
|
||||
$constraints .= " AND mnethostid = :mnethostid";
|
||||
}
|
||||
|
||||
if ($idsubselect) {
|
||||
$constraints .= " AND id IN (SELECT id FROM {user} WHERE {$idsubselect})";
|
||||
}
|
||||
|
||||
// Get all the basic user data.
|
||||
try {
|
||||
// Make sure that there's only a single record that matches our query.
|
||||
|
||||
Reference in New Issue
Block a user