Welcome to php club

PHP FAQ from PHPclub.ru: IdByUrlSpeed ...

Начало | Каталог | Изменения | НовыеКомментарии | Вам запрещён доступПользователи | Вам запрещён доступРегистрация | Вход:  Пароль:  

Получение id страницы по URL. Скорость.

Сегодня я опять играюсь с профайлером :) В общем мне кажется, что заметка будет полезной для тех, кто хочет иметь у себя ЧПУ и быстрый способ получения требуемой страницы.
В заметке будет рассматриваться сайт который использует списки смежности для хранения дерева. Вообще способ получения id страницы по url был описан еще до меня здесь.
Здесь я просто предложу два своих способа и сравню их скорости.
Способ 1.
Здесь для получения id страницы мы пройдемся по url и выполним по запросу на каждый уровень вложенности. Легче посмотреть код, чем понять что я написал :)

<?php
function get_id($path)
{
    
$uri_parts=explode('/'$path);
    
$last_parent=0;
    for(
$x=0$x<count($uri_parts); $x++)
    {
         
mysql_query("select id from test where parent='".$last_parent."' 
                and alias='"
.mysql_real_escape_string($uri_parts[$x])."'");
         list(
$last_parent)=mysql_fetch_row();
    }
    return 
$last_parent;
}
?>

Т.е. если у нас будет адрес about/contacts/branch1 эта функция выполнит три запроса для получения искомого id страницы branch1.


Способ 2.
Есть альтернативный вариант с применением таблиц, которые присоединяют сами себя к себе же :) (self-joins). Вот он:

<?php
function get_id($path)
{    
    
$uri_parts=explode('/'$path);
    
$query_joins="";
    
$query_where="where t1.alias='".$uri_parts[0]."'";
    
    for(
$x=1$x<count($uri_parts); $x++)
    {
        
$query_joins.=" left join test as t".($x+1)." on t".($x+1).".parent = t".$x.".id ";
        
$query_where.=" and t".($x+1).".alias = '".mysql_real_escape_string($uri_parts[$x])."' ";        
    }
    
mysql_query("select t".$x.".id from test as t1".$query_joins.$query_where);    
    list(
$xid)=mysql_fetch_row();
    return 
$xid;   
}
?>

Результат выполнения тот же.
А теперь самое интересное. Я обещал замеры и производительность. Так вот несмотря на то, что self-join должны по идее становится медленее с каждой новой присоединенной таблицей (так написано в этой статье ), они оказываются намного быстрее чем вариант с запросом на уровень сложенности (вариант 1). Не буду голословным а просто приведу результаты профайлинга. Об условиях: тесты производились на машине со след. конфигурацией: CPU 2.5 GHz, RAM 512 MB, CentOS 4.2, Apache 1.3, PHP 5.1.2, MySQL 5.0.16. В тестовую таблицу было забито 11280 записей. Сама таблица состояла из четырех полей: id(INT), parent(INT), alias(VARCHAR 15), article(TEXT). Данные были абсолютно реальными, т.е. не сгенерированные спец. скриптом сочетания из одной-двух букв а настоящие слова и статьи. Путь состоял из 10 компонентов (уровень вложенности 10).
Теперь собственно результаты:
вариант 1- среднее время 102ms,
вариант 2- среднее время 15ms.
Вывод очевиден. Недостаток self-join заключается в ограничении на количество присоединяемых таблиц (уровень вложенности).


 
Комментариев нет. [Показать комментарии/форму]