This pairs with http://drupal.org/node/625898
Before: Executed 595 queries in 207 milliseconds.
After: Executed 158 queries in 95.37 milliseconds.
I changed drupal_lookup_path() to accept $path as an array of paths and use src in(....). I changed menu_tree_check_access to call drupal_lookup_path('alias', $paths). menu_tree_check_access has a big list of node ids that are selected from the database in one hit. Later, when drupal_lookup_path() is asked to find an alias, the request is answered from the cache. Stats provided by devel module.

After making the change for menu and path, I though that the number of calls could be reduced by menu accepting the aliases from drupal_lookup_path and applying them direct to the menu instead of individual calls to path for the individual aliases. Either way, the system workload is reduced.

Comments

peterx’s picture

Title: Speed up path alias lookups in menu links » menu speedup when using path alias
Version: 7.x-dev » 6.14
Category: task » feature

I originally changed menu_tree_check_access to preload the cache in drupal_lookup_path then I tracked down the call to drupal_lookup_path and changed menu_tree_check_access to pass the alias so that drupal_lookup_path is not called, eliminating the need for the cache on these items. The alias did not pass on my first attempts so I changed menu_tree_output as shown below. Here are performance stats from devel for a different page.

Before: Executed 616 queries in 224.26 milliseconds.
After: Executed 178 queries in 97.14 milliseconds.
Double check with code out: Executed 614 queries in 217.59 milliseconds.
Double check with code back in: Executed 178 queries in 90.94 milliseconds.

Checking where drupal_lookup_path is used. Trace back:
drupal_lookup_path(includes/path.inc, 156)
drupal_get_path_alias(includes/common.inc, 1475)
url(includes/common.inc, 1601)
l(sites/all/themes/christmas/template.php, 311)
christmas_menu_item_link(, )
call_user_func_array(includes/theme.inc, 617)
theme(includes/menu.inc, 758)
menu_tree_output(includes/menu.inc, 760)
menu_tree_output(includes/menu.inc, 724)
menu_tree(sites/all/themes/christmas/page.tpl.php, 112)
include(includes/theme.inc, 1020)
theme_render_template(includes/theme.inc, 686)
theme(index.php, 36)

menu_tree_check_access changed to accumulate node paths then request the aliases in one big hit.

function menu_tree_check_access(&$tree, $node_links = array()) {

  if ($node_links) {
    // Use db_rewrite_sql to evaluate view access without loading each full node.
    $nids = array_keys($node_links);
  $paths = array();
    $placeholders = '%d'. str_repeat(', %d', count($nids) - 1);
    $result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.status = 1 AND n.nid IN (". $placeholders .")"), $nids);
    while ($node = db_fetch_array($result)) {
      $nid = $node['nid'];
      $paths[$nid] = 'node/' . $nid;
      foreach ($node_links[$nid] as $mlid => $link) {
        $node_links[$nid][$mlid]['access'] = TRUE;
      }
    }
    // aliases['src'] = dst
    $aliases = drupal_lookup_path('alias', $paths);
    
    foreach($paths as $nid => $path)
    {
	    if(isset($aliases[$path]))
	    {
      foreach ($node_links[$nid] as $mlid => $link) {
        $node_links[$nid][$mlid]['alias'] = $aliases[$path];
      }
	    }
    }
  }
  _menu_tree_check_access($tree);
  return;
}

Code added in menu_tree_output:

    if ($i == $num_items - 1) {
      $extra_class = 'last';
    }
    
	if(isset($data['link']['alias']))
		{
		$data['link']['href'] = $data['link']['alias'];
		$data['link']['localized_options']['alias'] = true;
		}
	
    
    $link = theme('menu_item_link', $data['link']);
sun’s picture

Title: menu speedup when using path alias » Speed up path alias lookups in menu links
Version: 6.14 » 7.x-dev
Category: feature » task

Please provide a proper patch for D7.

wuf31’s picture

Title: menu speedup when using path alias » Speed up path alias lookups in menu links
Version: 6.14 » 7.x-dev
Category: feature » task

looks interesting, subscribe..

Status: Active » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.