Новости Joomla

0 Пользователей и 1 Гость просматривают эту тему.
  • 7 Ответов
  • 935 Просмотров
*

novikov82

  • Новичок
  • 9
  • 3 / 0
Попал в довольно гнилую ситуацию: создал в магазине более 3 тысяч категорий, начала феерически тормозить админка на редактировании категорий и товаров.
Беглый анализ дал понять, что затык наступает в функции getTreeAllCategories из модели categories.
В принципе, не мудрено, в функции есть фрагмент:
Код
                    foreach ($categories as $key => $category){
                        ...
                        while ($category_parent_id || $i < 1000) {
                            foreach ($originalCategories as $originalKey => $originalCategory){
                                ...
                            }
                            $i++;
                        }
Три вложенных цикла, два из них размерностью порядка тысяч, да еще, как я понимаю, глубина вложенности категорий, в общем, несколько десятков миллионов итераций набирается.
Кто как с этим борется? Можно ли улучшить работу магазина в админке, не исправляя авторского кода? Мне в голову ничего пока не пришло - в этой функции ни одного плагина нет.

UPD
Функция buildTreeCategory работает еще ужаснее :( пришлось пока забить два грубых костыля.
« Последнее редактирование: 30.09.2015, 00:37:26 от novikov82 »
*

dmitry_stas

  • Легенда
  • 13151
  • 1234 / 8
Беглый анализ дал понять, что затык наступает в функции getTreeAllCategories из модели categories.
указанный кусок кода выполняется только если isset($filter['text_search']) && !empty($filter['text_search']. соответственно, там далеко не несколько десятков миллионов проходов.

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

Функция buildTreeCategory работает еще ужаснее :( пришлось пока забить два грубых костыля.
есть тема Что нужно доделать в ЖШ. разработчики ее читают и если просьбы/советы действительно стоящие - то они включают это в апдейты. если вы считаете, что вам есть что предложить в плане оптимизации - предлагайте. уверен, что если будет что слушать, то вы будете услышаны :)
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций
*

novikov82

  • Новичок
  • 9
  • 3 / 0
указанный кусок кода выполняется только если isset($filter['text_search']) && !empty($filter['text_search']. соответственно, там далеко не несколько десятков миллионов проходов.
Да, вы правы, дело не в этом кусочке, а в функции recurseTree, она вызывается в другом месте и используется для построения дерева категорий.
Цитировать
приходилось иметь дело с магазинами, у которых было похожее количество категорий. не видел особых проблем. но вообще конечно согласен с вами, что там есть что оптимизировать.
Думаю, дело не столько в количестве категорий, а в большом уровне вложенности (так уж у меня получилось, что магазин сильно ветвится). Для рекурсии это, очевидно, важно.

И непонятно, как решать проблему. Я пишу о том, что мои костыли грубые - ориентированы под мою задачу, на других задачах не прокатит. Поэтому и разработчикам как-то пока нечего предложить. Придется подумать.
*

dmitry_stas

  • Легенда
  • 13151
  • 1234 / 8
сделайте ради интереса
Код
echo microtime(true);
до и после вызова recurseTree(), чтобы посмотреть сколько функция выполняется по времени.
думается мне что проблема все таки не в ней...
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций
*

novikov82

  • Новичок
  • 9
  • 3 / 0
сделайте ради интереса
Код
echo microtime(true);
до и после вызова recurseTree(), чтобы посмотреть сколько функция выполняется по времени.
думается мне что проблема все таки не в ней...
Сделал. Дело в ней :(
Ради эксперимента вставил такую штуку:
Код
function recurseTree($cat, $level, $all_cats, &$categories, $is_select) {
    $probil = '';
    if($is_select) {
        for ($i = 0; $i < $level; $i++) {
            $probil .= '-- ';
        }
        $cat->name = ($probil . $cat->name);
        $categories[] = JHTML::_('select.option', $cat->category_id, $cat->name,'category_id','name' );
    } else {
        $cat->level = $level;
        $categories[] = $cat;
    }
    foreach ($all_cats as $categ) {
   
        echo "x"; // <--- добавил для проверки

        if($categ->category_parent_id == $cat->category_id) {
            recurseTree($categ, ++$level, $all_cats, $categories, $is_select);
            $level--;
        }
    }
    return $categories;
}
Получил на выходе 7 миллионов иксов. Мне кажется, многовато.
*

dmitry_stas

  • Легенда
  • 13151
  • 1234 / 8
какое время выполнения получили?
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций
*

novikov82

  • Новичок
  • 9
  • 3 / 0
какое время выполнения получили?
Пять секунд на локальной машине, на сервере не проверял, но, наверное, чуть меньше.
Но вообще диалог с вами подтолкнул на мысль. Функция recursiveTree написана, по сути, довольно бездарно. В рекурсии стоит цикл по всем категориям, в котором ищутся дочерние категории по идентификатора родителя. И при том количестве категорий, которое обычно бывает в магазинах, это не заметно. А я вот попался...
В общем, поправил ее малой кровью с использованием ассоциативного массива:
Код
function recurseTree($cat, $level, $all_cats, &$categories, $is_select) {
   static $cat_by_parent = null;
   if(!$cat_by_parent)
   {
$cat_by_parent = array();
foreach ($all_cats as $categ)
{
  if(!$cat_by_parent[$categ->category_parent_id])
$cat_by_parent[$categ->category_parent_id] = array();
  $cat_by_parent[$categ->category_parent_id][] = $categ;
}
    }

    $probil = '';
    if($is_select) {
        for ($i = 0; $i < $level; $i++) {
            $probil .= '-- ';
        }
        $cat->name = ($probil . $cat->name);
        $categories[] = JHTML::_('select.option', $cat->category_id, $cat->name,'category_id','name' );
    } else {
        $cat->level = $level;
        $categories[] = $cat;
    }
if($cat_by_parent)
    if(count($cat_by_parent[$cat->category_id]))
{
foreach ($cat_by_parent[$cat->category_id] as $categ) {
recurseTree($categ, ++$level, $all_cats, $categories, $is_select, $cat_by_parent);
$level--;
}
}
    return $categories;
}

Буду писать в предложения улучшений... Спасибо :)
*

dmitry_stas

  • Легенда
  • 13151
  • 1234 / 8
угу, норм решение. я бы тоже так писал - исходя из цикла по родительским. по хорошему конечно тут тоже нужны проверки вне циклов, но и так насколько я вижу количество проходов снизилось с n*n до n+n. итого у вас 6 тыс вместо 7 млн :)
Тут дарят бакс просто за регистрацию! Успей получить!
Все советы на форуме раздаю бесплатно, то есть даром. Индивидуально бесплатно консультирую только по вопросам стоимости индивидуальных консультаций
Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Модуль (компонент, плагин) вывода категорий Жш

Автор stitch808

Ответов: 4
Просмотров: 676
Последний ответ 07.11.2022, 15:01:21
от stitch808
Цена "от" на странице списка категорий товаров (цена самого дешёвого товара)

Автор goga_pgasovav

Ответов: 3
Просмотров: 441
Последний ответ 14.10.2021, 14:13:38
от goga_pgasovav
СТраница с названиями категорий и списком всех товаров

Автор dron

Ответов: 8
Просмотров: 550
Последний ответ 08.12.2020, 21:32:00
от kit2m2
Список заказов (админка) - Вывести общий вес все товаров в заказе

Автор kit2m2

Ответов: 1
Просмотров: 578
Последний ответ 06.10.2020, 20:42:13
от Taatshi
Алиас вложенных категорий

Автор AlexB

Ответов: 8
Просмотров: 835
Последний ответ 24.01.2020, 22:26:06
от AlexB