5. Как ускорить Drupal в несколько раз

Рецепт взят со страницы: http://freecoder.ru/node/18 и адаптирован для Drupal6


Уменьшение запросов к БД в path.inc. Лезть в код и править файл path.inc. Заменяем:

<?php
function drupal_init_path() {
  if (!empty(
$_GET['q'])) {
    
$_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
  }
  else {
    
$_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage''node'));
  }
}
?>

на

<?php
function drupal_init_path() {
  global 
$map_alias;
  
  
$c=count($map_alias);
  if (empty(
$c))
  {
  
$sql "SELECT src,dst,language FROM {url_alias} ";
  
$res=db_query($sql);
    while( 
$row=db_fetch_array($res))
    {
      
$map_alias[$row['language']][$row['src']]=$row['dst'];
    }
  }

  if (!empty(
$_GET['q'])) {
    
$_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/'));
  }
  else {
    
$_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage''node'));
  }
}
?>

Далее, заменяем:

<?php
function drupal_lookup_path($action$path ''$path_language '') {
  global 
$language;
  
// $map is an array with language keys, holding arrays of Drupal paths to alias relations
  
static $map = array(), $no_src = array(), $count;

  
$path_language $path_language $path_language $language->language;

  
// Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
  
if (!isset($count)) {
    
$count db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
  }

  if (
$action == 'wipe') {
    
$map = array();
    
$no_src = array();
    
$count NULL;
  }
  elseif (
$count && $path != '') {
    if (
$action == 'alias') {
      if (isset(
$map[$path_language][$path])) {
        return 
$map[$path_language][$path];
      }
      
// Get the most fitting result falling back with alias without language
      
$alias db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC"$path$path_language));
      
$map[$path_language][$path] = $alias;
      return 
$alias;
    }
    
// Check $no_src for this $path in case we've already determined that there
    // isn't a path that has this alias
    
elseif ($action == 'source' && !isset($no_src[$path_language][$path])) {
      
// Look for the value $path within the cached $map
      
$src '';
      if (!isset(
$map[$path_language]) || !($src array_search($path$map[$path_language]))) {
        
// Get the most fitting result falling back with alias without language
        
if ($src db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC"$path$path_language))) {
          
$map[$path_language][$src] = $path;
        }
        else {
          
// We can't record anything into $map because we do not have a valid
          // index and there is no need because we have not learned anything
          // about any Drupal path. Thus cache to $no_src.
          
$no_src[$path_language][$path] = TRUE;
        }
      }
      return 
$src;
    }
  }

  return 
FALSE;
}
?>

на:

<?php
function drupal_lookup_path($action$path ''$path_language '') {
  global 
$language;
  global 
$map_alias;
  
// $map is an array with language keys, holding arrays of Drupal paths to alias relations
  
static $map = array(), $no_src = array(), $count;

  
$path_language $path_language $path_language $language->language;

  
// Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
  
if (!isset($count)) {
    
$count db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
  }

  if (
$action == 'wipe') {
    
$map = array();
    
$no_src = array();
    
$count NULL;
  }
  elseif (
$count && $path != '') {
    if (
$action == 'alias') {
    
      if (isset(
$map_alias[$path_language][$path])) {
        
$map[$path_language][$path] = $map_alias[$path_language][$path];
        return 
$map[$path_language][$path];
      }
      
// Get the most fitting result falling back with alias without language
      
$alias db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC"$path$path_language));
      
$map[$path_language][$path] = $alias;
      return 
$alias;
    }
    
// Check $no_src for this $path in case we've already determined that there
    // isn't a path that has this alias
    
elseif ($action == 'source' && !isset($no_src[$path_language][$path])) {
      
// Look for the value $path within the cached $map
      
$src '';
      if (!isset(
$map[$path_language]) || !($src array_search($path$map[$path_language]))) {
        
// Get the most fitting result falling back with alias without language
        
if ($src db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY langua
ge DESC"
$path$path_language))) {
          
$map[$path_language][$src] = $path;
        }
        else {
          
// We can't record anything into $map because we do not have a valid
          // index and there is no need because we have not learned anything
          // about any Drupal path. Thus cache to $no_src.
          
$no_src[$path_language][$path] = TRUE;
        }
      }
      return 
$src;
    }
  }
  return 
FALSE;
}
?>

в итоге получаем один запрос к базе вместо 60-70

Кого ломает делать это всё руками, берить патч для Drupal 6.13 в прицепе к этому рецепту и патчите.

ВложениеРазмер
path.diff1.26 kb

Комментарии

Падают отдельные алиасы

Здравствуйте! Внедрил приведённый здесь код, и получил, помимо действительно ускорения загрузки страниц, также надпись "Страница не найдена" по отдельным ссылкам. При откате назад path.inc всё снова начинает работать. В чём тут может быть дело? Кэш чистил :)

Я сам данный код не писал, а

Я сам данный код не писал, а использовал готовый рецепт. У меня он работал прекрасно.
С ходу могу высказать предположение, что судя по запросу могут быть проблемы на многоязычных сайтах ибо сами видите:
...AND language IN('%s', '')...
Также, поскольку данный механизм обходит что-то стандартное, то возможны проблемы с модулями, которые как-то хитро работают с вариантами (алиасами).
Повторюсь - это только предположения.

Спасибо, попробую разобраться

Спасибо, попробую разобраться