Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Here is a snippet of code from the function password_policy_cron() in password_policy.module:561:
// Get all users' last password change time. We don't touch blocked accounts.
$query = db_select('users', 'u', array('target' => 'slave'));
$query->leftJoin('password_policy_history', 'p', 'u.uid = p.uid');
$query->leftJoin('password_policy_expiration', 'e', 'u.uid = e.uid');
$result = $query->fields('u', array('uid', 'created'))
->fields('p', array('created'))
->fields('e', array('pid', 'unblocked', 'warning'))
->condition('u.uid', 0, '>')
->condition('u.status', 1)
->orderBy('p.created)
->execute();
The resulting SQL query is like:
SELECT u.uid AS uid, u.created AS created, p.created AS p_created, e.pid AS pid, e.unblocked AS unblocked, e.warning AS warning
FROM
users u
LEFT OUTER JOIN password_policy_history p ON u.uid = p.uid
LEFT OUTER JOIN password_policy_expiration e ON u.uid = e.uid
WHERE (u.uid > 0) AND (u.status = 1) ORDER BY p.created ASC;
This query get the list of the users in the system, with a line for every time the user change its password multiply every time the user received an expiration warnings. This can be a lot of data, especially for systems with a lot of users and some years of uptime. However only the last record for each uid is used in the following code.
My proposal is to change this query to obtain only the needed rows. A possible solution can be this:
SELECT u.uid AS uid, u.created AS created, p.created AS p_created, e.pid AS pid, e2.unblocked AS unblocked, e.warning AS warning
FROM
users u
LEFT OUTER JOIN (SELECT uid, max(created) as created FROM password_policy_history GROUP BY uid) p ON u.uid = p.uid
LEFT OUTER JOIN (SELECT uid, pid, max(warning) as warning FROM password_policy_expiration GROUP BY uid, pid) e
ON u.uid = e.uid LEFT OUTER JOIN (SELECT uid, max(unblocked) as unblocked FROM password_policy_expiration GROUP BY uid) e2 ON u.uid = e2.uid
WHERE (u.uid > 1) AND (u.status = 1);
Regards,
Comment | File | Size | Author |
---|---|---|---|
#13 | Screen Shot 2017-01-11 at 5.34.18 PM.png | 130.55 KB | Manav |
#13 | Screen Shot 2017-01-11 at 4.46.11 PM.png | 125.12 KB | Manav |
#7 | improve_user_data_query-2833785-7.patch | 1.71 KB | JayKandari |
|
Comments
Comment #2
JayKandariI think version should be 7.x-1.x-dev . kindly confirm.
Comment #3
mithenks CreditAttribution: mithenks commentedComment #4
JayKandariComment #5
JayKandariModified query as described in Issue description. Kindly Review.
Thanks!
Comment #7
JayKandariPatch updated. Kindly Review.
Comment #8
JayKandari#7 should work. Kindly Review.
Comment #9
Manav CreditAttribution: Manav as a volunteer and at QED42 commentedComment #10
Manav CreditAttribution: Manav as a volunteer and at QED42 commentedComment #11
Manav CreditAttribution: Manav as a volunteer and at QED42 commentedComment #12
Manav CreditAttribution: Manav as a volunteer and at QED42 commentedComment #13
Manav CreditAttribution: Manav as a volunteer and at QED42 commentedThis Patch is working fine for me. After applied this patch the query return per the above description. Attaching 2 screen-shot before and after applied the patch.
Comment #14
AohRveTPV CreditAttribution: AohRveTPV commented#7 no longer applies.