PHP большой тормоз?

Статус
В этой теме нельзя размещать новые ответы.

webikdddorf

Новичок
> Всё-таки ответь, зачем тебе это надо-то?

Заказчик попросил немного оптимизировать магазин. Вот мне и пришла в голову, что можно сократить количество запросов в базу данных и переписать кусок кода отвечающий за вывод дерева категорий.
Дано 1.5 тыс. категорий и 300 тыс товаров.
Результат До: 2.6 секунды. 3100 запросов в базу.
Результат После: 1.9 секунды. 29 запросов в базу.

(P.s. это результаты на локальной машине, на боевом сервере цифры естественно все в разы быстрее и покупателю незаметно)

Таким образом перенеся построение дерева категорий с плеч mysql на php я выиграл и время и снял кучу запросов в базу.


> Кстати, по поводу этой "оптимизации": сокращать количество IO операций это, конечно, хорошо, но закон "не делай средствами PHP то, что можно сделать средствами базы данных" ещё никто не отменял.

Нет, в данном случае я полагаю возвращаться к тысячам запросам к базе это грех на душу ))
 

Breeze

goshogun
Команда форума
Партнер клуба
Результат До: 2.6 секунды. 3100 запросов в базу.
Результат После: 1.9 секунды. 29 запросов в базу.
как-то не сильно полегчало.
есть мнение, что и в запросах, и в базе, и в коде не все гладко.

и до сих пор непонятно, зачем это нужно? опиши исходные данные и что должно плучаться в итоге.
 

dimagolov

Новичок
webikdddorf, у тебя 100% или структура дерева неправильная, или ты ее неправильно запрашиваешь. раскажи как храниться дерево.

кроме того, неужели тебе всегда надо выводить все 300 тыс товаров во всех 1500 категориях? если название каждого товара/категории 10 символов, то это 3 с лишним мегабайта текста не считая html тегов. ну не в жизнь не поверю, что у тебя все странички в магазине больше 3-х мег.

-~{}~ 01.12.08 11:46:

да, тысячи запросов к базе это как раз "не средствами БД". средствами БД это когда запрос один и выдает уже отформатированную-отсортированную таблицу, которую надо только вывести в html без какой-либо сортировки.
 

Angerslave

Новичок
Wicked
У БД есть репликация. Но в любом случае, это, окей, не закон - правило, действует, особенно касательно таких случаев, как выборка SELECT * FROM table и потом на PHP эмулирование WHERE.

webikdddorf
> Дано 1.5 тыс. категорий и 300 тыс товаров.
Почему-то я уверен, что из них максимум 20 категорий и 100 товаров нужно в данный момент, если это не общий прайс, который можно закешировать.
 

webikdddorf

Новичок
Да очень просто хранится - CatID, ParentID, и далее всякая лабуда типо имя категории, сортировка и т.д.
И базы выбирается одним запросом вся эта херь, и сразу записывается в два массива, в один все сразу, в другой только CatID и ParentID.

Ну а по поводу "выводить", да нужно выводить все, это называется как бы многоуровневое меню категорий, тоесть сперва отображаются 10 главных, а потом плюсиками можно пораскрывать все 1500 тысячи.

Так вот для каждой категории происходит операция по выборке из маленького массива( CatID, ParentID). Категорий 1500 и массив из 1500 элементов, значит для вывода дерева выполняется 1500 операций по выборке из массива. Т.е. для каждой категории выбираются ее паренты и выводятся следующей ступенью, а там тоже самое делается и т.д.. Ну а в самом скрипте вывода уже ключи выбранные из маленького массива подставляются в большой $lalala[$key] и оттуда уже берутся все данные типо имени и т.д.
Для наглядности:
global $globalcat(большой массив), $globalcatmin(минимассив CatID, ParentID);

$categor = array_keys ($globalcatmin, (int)$parent); тут раньше были запросы в базу, которых набегало за все категории около 3000


foreach ($categor as $categoryrow)
{
$row = $globalcat[(int)$categoryrow];
if (!file_exists("pictures/".$row["picture"])) $row["picture"] = "";
$row["name"] = Text($row["name"]);
и т.д. уже пошла работа с данными категории.

Оптимизировать еще больше нельзя, только если дерево периодически генерировать в статику и хранить где-то, тогда по времени выиграем. А так уже все что можно оптимизировано.

Собственно в этой теме я и поднял вопрос, что php 0.6 секунды обрабатывает 1500 раз массив из 1500 элементов. Это чень медленно.
 

pilot911

Новичок
по всей видимости, неправильно каждый раз строить дерево из 1000 категорий

можно либо один раз построить и сохранить в кэше, либо строить последовательно по уровням по мере запросов пользователя

типа-выводим только первый уровень - кликаем, например, на Игрушки, далее показываем через ajax все child Игрушек, и тп
 

webikdddorf

Новичок
сперва так и было, заказчик включил потом полное меню, ему оно больше нравится.
 

Breeze

goshogun
Команда форума
Партнер клуба
webikdddorf

у тебя уровень вложенности в категориях какой?
 

webikdddorf

Новичок
Вообще уровень вложенности, но более 4 уровней я еще ни в одном магазине на свете не видел. Так и тут - не более 4.
 

Angerslave

Новичок
> php 0.6 секунды обрабатывает 1500 раз массив из 1500 элементов. Это чень медленно.
PHP - не ассемблер, а HyperText Preprocessor, поэтому космических скоростей требовать от него глупо. В любом случае, уже в разных формах чуть ли не в каждом посте написали - ошибка в архитектуре, тот же результат можно получить за куда меньшее время на том же "большом тормозе php".
 

Wicked

Новичок
Angerslave
У БД есть репликация. Но в любом случае, это, окей, не закон - правило, действует, особенно касательно таких случаев, как выборка SELECT * FROM table и потом на PHP эмулирование WHERE
Ну моему утверждению это не противоречит, ибо как раз присутствие where в запросе, как правило, облегчает базе жизнь.
И да, репликация - не панацея.

-~{}~ 01.12.08 22:39:

Собственно в этой теме я и поднял вопрос, что php 0.6 секунды обрабатывает 1500 раз массив из 1500 элементов. Это чень медленно.
в том то и дело, что чтобы построить дерево, не обязательно делать столько работы. Можно обойтись просто 1500-ми итерациями. Я об этом писал касательно хэш-таблиц. Что такое хэш-таблицы, их сильные стороны, и какое отношение они имеют к пхп можно узнать в интернете. А там и написать код уже пара пустяков.
 

Breeze

goshogun
Команда форума
Партнер клуба
при уровне вложенности 4 запросов тоже может быть всего 4

1500*1500 = 2.250.000 итераций + всякие дополнительные шняжки. это уже не хрен собачий.
 

phprus

Moderator
Команда форума
На тему построения дерева:
http://phpclub.ru/talk/showthread.php?s=&threadid=108984&rand=18
Там-же приведен алгоритм Wickedа по конвертировании результата выборки во вложенный массив-дерево.

webikdddorf
Ну а по поводу "выводить", да нужно выводить все, это называется как бы многоуровневое меню категорий, тоесть сперва отображаются 10 главных, а потом плюсиками можно пораскрывать все 1500 тысячи.
Мне кажется что тут будет гораздо лучше вариант а AJAX-подгрузкой для тех клиентов у которых он(ajax) есть и перезагрузка страницы с разворачиванием подменю для тех у кого его нет(меньшинство пользователей). Так как 98% пользователей все подменю будут не нужны, то это должно сократить и нагрузку на сервер и трафик.
 

webikdddorf

Новичок
> при уровне вложенности 4 запросов тоже может быть всего 4

А у меня всего один :) А всего 29, остальные 28 это на остальное для магазина.

> 1500*1500 = 2.250.000 итераций + всякие дополнительные шняжки. это уже не хрен собачий.

И вправду, какая страшная цифра, ухты.
 

Breeze

goshogun
Команда форума
Партнер клуба
webikdddorf

только у меня 5 за 0,023 отрабатывают на 1863 элементах при 1863 итерациях на нотебуке.

И вправду, какая страшная цифра, ухты.
в данном случае -- страшная.
 

webikdddorf

Новичок
Боюсь что алгоритм Wickedа для меня труден в понимании ))
В общем если можно подставьте туда мои массивы из куска кода что я давал, дабы я смог оценить этот алгоритм. Пока не совсем въехал.

$tree = array(0 => null);
$root =& $tree[0];
foreach($data as $node) {
if(!isset($tree[$node["parent_id"]])) {
$tree[$node["parent_id"]] = array();
}
$tree[$node["parent_id"]][$node["id"]] =& $tree[$node["id"]];
}
print_r($root);

-~{}~ 01.12.08 20:02:

To Breeze, это был не смех, я правда ужаснулся. 2.250.000 итераций.
 

Breeze

goshogun
Команда форума
Партнер клуба
$tree[$node["parent_id"]][] = $node;

задавая parent_id ты всегда будешь получать либо его чайлдов, либо ничего.

-~{}~ 01.12.08 20:46:

пока заняться нечем, загнал свои тестовые записи в отдельную таблицу. с одним запросом за 0,011 строится дерево. +50% =)
 

Nicholas

Новичок
webikdddorf

А тебе точно необходимы жесткие ссылки?
Чо-то я слышал, что они сильно тормозят. (сам не проверял).
Без этого: =& все разве не работает?
 

Wicked

Новичок
Nicholas
1) да, этому алгоритму нужны ссылки.
2) ссылки в пхп не тормозят. Да и если бы очень сильно тормозили, этот алгоритм все равно выиграл бы у алгоритма ТС.
3) а самому проверить?
 

webikdddorf

Новичок
Я все еще не разобрался, Wicked, можешь подставить мои массивы в свой код?

-~{}~ 02.12.08 09:51:

Хотя вообще это уже не важно, я просто добавил в базу поле где записывается количество подкатегорий в категории, и теперь идет только 1500 прогонов массива, вместо 1500^2 в квадрате. Время сократилось до 0.2 сек. (это на весь скрипт, а на массив совсем мизер уходит от этого)(На домашнем).

-~{}~ 02.12.08 10:01:

Есть такое грозное слово - ТАК СКАЗАЛ ЗАКАЗЧИК. В общем то проблему уже успешно решил. Дальше можно не обсуждать.
Ну только если Wicked найдет время, пусть покажет как можно сделать на его алгоритме, а так вроде во всем разобрались.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху