On my site I am seeing user_load() being called 14 times just while viewing a user account. Each of those is doing a query to load the same user_terms data.

This is easy to fix:

function user_terms_load_profile(&$account) {
  static $user_terms = array();
  if (isset($user_terms[$account->uid])) {
    $account->user_terms = $user_terms[$account->uid];
    return;
  }

  $terms  = array();
  $query = "SELECT u.tid, t.vid, t.name FROM {term_user} u 
    INNER JOIN {term_data} t ON t.tid = u.tid 
    INNER JOIN {vocabulary} v ON t.vid = v.vid 
    WHERE u.uid = %d
    ORDER BY v.weight, t.weight, t.name";
  $result = db_query($query, $account->uid);

  while ($term = db_fetch_array($result)) {
    $terms[$term['tid']] = $term;
  }

  $user_terms[$account->uid] = $account->user_terms = $terms;
}

This reduced my query count and time significantly.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

NancyDru’s picture

FileSize
1.31 KB

Here's a patch.

NancyDru’s picture

Assigned: Unassigned » NancyDru
joachim’s picture

Status: Needs review » Needs work

This is actually due to a bug in Core which I filed ages ago and is almost certainly not going to get fixed on D6. So I guess it makes sense to implement what is a pretty sane workaround ourselves.

Patch looks good, though I'd like it without the whitespace changes please :)

NancyDru’s picture

Status: Needs work » Needs review
FileSize
950 bytes

I have fixed the core problem too - it's so simple.

joachim’s picture

Status: Needs review » Fixed

Committed, thanks.

#945300 by NancyDru: Added static caching as workaround for multiple calls by core to user_terms_load_profile().

The core bug is #685806: hook_user op 'load' called multiple times on user account page; queries run needlessly, BTW.

NancyDru’s picture

Thank you, Joachim. There are many user_load bugs. I am at a point where I am waiting for answers on several issues, so I was working on performance stuff.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.