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,

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mithenks created an issue. See original summary.

JayKandari’s picture

I think version should be 7.x-1.x-dev . kindly confirm.

mithenks’s picture

Version: 7.x-2.x-dev » 7.x-1.x-dev
JayKandari’s picture

Assigned: Unassigned » JayKandari
JayKandari’s picture

Status: Active » Needs review
FileSize
1.69 KB

Modified query as described in Issue description. Kindly Review.

Thanks!

Status: Needs review » Needs work

The last submitted patch, 5: improve_user_data_query-2833785-5.patch, failed testing.

JayKandari’s picture

Patch updated. Kindly Review.

JayKandari’s picture

Assigned: JayKandari » Unassigned
Status: Needs work » Needs review

#7 should work. Kindly Review.

Manav’s picture

Issue summary: View changes
Manav’s picture

Issue summary: View changes
Manav’s picture

Issue summary: View changes
Manav’s picture

Assigned: Unassigned » Manav
Manav’s picture

Assigned: Manav » Unassigned
Status: Needs review » Reviewed & tested by the community
FileSize
125.12 KB
130.55 KB

This 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.

AohRveTPV’s picture

Status: Reviewed & tested by the community » Needs work

#7 no longer applies.