За последние 24 часа нас посетили 17695 программистов и 1657 роботов. Сейчас ищут 959 программистов ...

Оптимизация и обработка запросов

Тема в разделе "PHP и базы данных", создана пользователем doremidon, 17 апр 2010.

  1. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Доброго дня!

    Пожалуйста, помогите оптимизировать..
    Дерево структуры в MySQL имеет следующий вид:

    ряд 1
    ряд 1.1
    ряд 1.1.1
    ряд 1.1.2
    ряд 1.1.3
    ряд 1.1.4
    ряд 2.1
    ряд 1.2.1
    ряд 1.2.2
    ряд 1.2.3
    ряд 2
    ряд 2.1
    ряд 2.1.1
    ряд 2.1.2
    ряд 2.1.3
    ряд 2.1.4
    ряд 2.1
    ряд 2.2.1
    ряд 2.2.1.1
    ряд 2.2.1.2
    ряд 2.2.1.3
    ряд 2.2.1.4

    Вообщем вложенность бесконечная.

    Общее число рядов сейчас 500.

    База данных имеет следующий вид:
    id - идентификатор ряда
    par - id родителя
    name - имя ряда
    num - порядковый номер в соответствующем родителе
    ...


    Тоесть для начальных рядов "par" = 0.
    Соответственно для вложенных рядов нужно указать соответствующий ID.

    id | par | name | num
    1 | 0 | ряд 1 | 1
    2 | 1 | ряд 1.1 | 1
    3 | 2 | ряд 1.1.1 | 1
    4 | 2 | ряд 1.1.2 | 2
    5 | 2 | ряд 1.1.3 | 3


    Проблема с нагрузкой при выводе/показа всего дерева.


    Вариант 1:
    PHP:
    1.  
    2. <?php
    3. class TREE
    4. {
    5.     function Index()
    6.     {
    7.         $result = SQL::SelectRol(" SELECT id, name FROM `tree` WHERE `par`='0' ORDER BY `num`");
    8.         while($row = mysql_fetch_assoc($result))
    9.         {
    10.             var_dump($row);
    11.             $this->Children($row['id']);
    12.         }
    13.     }
    14.  
    15.     function Children($id)
    16.     {
    17.         $result = SQL::SelectRol(" SELECT id, name FROM `tree` WHERE `par`='".$id."' ORDER BY `num` ");
    18.         while($row = mysql_fetch_assoc($result))
    19.         {
    20.             var_dump($row);
    21.             $this->Children($row['id']);
    22.         }
    23.     }
    24. }
    25.  
    Недостаток: общая обработка ~ 1.2 сек и очень много запросов к БД.


    Вариант 2:
    PHP:
    1.  
    2. <?php
    3. class TREE
    4. {
    5.     private  $tree = array();
    6.     function Index($sqlSectionDop) {
    7.         $con = NULL;
    8.         $this->tree = SQL::FetchAssoc(" SELECT id, name, par FROM `tree` ORDER BY `num` ");
    9.         # получаем всё дерево системы в массив и начинаем обработку
    10.        foreach ($this->tree as $key => $value) {
    11.             if($value['par']==0){
    12.                 var_dump($value);
    13.                 $id = $value['id'];
    14.                 unset ($this->tree[$key]);
    15.                 $this->Children($id);
    16.             }
    17.         }
    18.     }
    19.  
    20.     function Children($id) {
    21.         $con = NULL;
    22.         foreach ($this->tree as $key => $value) {
    23.             if($value['par']==$id){
    24.                 var_dump($value);
    25.                 $id = $value['id'];
    26.                 unset ($this->tree[$key]);
    27.                 $this->Children($id);
    28.             }
    29.         }
    30.     }
    31. }
    32.  
    Недостаток: общая обработка ~ 0.18 сек и около 128 000 запросов к функции Children.


    Подскажите как оптимизировать!??
     
  2. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Насколько бесконечная?
    И что собрались оптимизировать?

    Если выводим ВСЕ дерево, то и выбираем ВСЕ данные за один запрос.

    Или вопрос в том, как обойтись без рекурсии?
     
  3. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Настолько насколько хватит бесконечно влаживать - всмысле бесконечно..

    Меня смущают некоторые цифры:

    Вариант 1:
    Недостаток: общая обработка ~ 1.2 сек и очень много запросов к БД.

    Вариант 2:
    Недостаток: общая обработка ~ 0.18 сек и около 128 000 запросов к функции Childer.


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

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    В реальной жизни бесконечные уровни вложенности практически не встречаются. Как и матрешки - все имеет свой предел.
    Это один элемент оптимизации.

    Второй элемент -
    Если у вас 500 элементов, то при при нормальной рекурсии у вас будет не более 500 обращений к функции.
    Пронаблюдайте, что происходит с массивом $this->tree после unset() и сколько элементов пробегает самый верхний foreach из метода index

    Ну и третий элемент -
    чтобы оптимизировать что-то - нужно четко понимать результат, который хочется получить. Вы можете себе нарисовать картинку конечного результата?
     
  5. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    1:
    Матрешки для чего?
    Вложенность папок к примеру существует!
    Бесконечно - разве настолько недостижимо?)

    2:
    Вообщем к нормальной рекурсии и хотелось бы дойти.
    Если посмотреть внимательно на "самый верхний foreach из метода index" можем получить:
    500 проходов foreach и отделение требуемых элементов из всех. Думаю, что тут может сильно варьироваться(1 - 1000).

    3:
    О какой картинке говорите?
     
  6. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    И она ограничена.

    Это не имеет смысла.

    Не может ничего варьироваться. Верхний цикл должен повторяться не больше чем есть элементов.
    Более того. Он должен динамически уменьшаться по мере удаления элементов из массива в рекурсивной функции.
    Т.е. фактическое число проходов в нем должно быть меньше 500 и равняться числу элементов 0го уровня.

    Почему у Вас не так? Что нужно сделать, чтобы было так?
     
  7. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Покажите ка пример где именно будет ограниченность в том принципе постройки, который я показал в первом посте?

    К чему вообще говорить о смысле бесконечности? Если считаете, что это бессмысленно, то это Ваша субъективаня оценка.

    Я показал как у меня. Если не ясно есть масса вариантов изменения, но сомневаюсь, что менять что-то желаете!

    После того как найду пути изменения - отпишу при запросе...

    Спасибо..
     
  8. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Там где захочется. Установить ограничение на глубину вложенности - будет вполне разумным.

    И не сомневайтесь. Мне менять точно ничего не нужно, это у Вас ведь код работает некорректно.

    Экий Вы медленно понимающий :)

    Это направление, в котором нужно думать -
     
  9. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    То как в идеале должно работать я и сам описал! или нет?

    Если считаете что можете изменить на что-то более подходящее - может скажите?

    Для чего впустую тратите время?
     
  10. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    doremidon
    Во-первых, время впустую я могу тратить только, если человек безнадежно глуп - и с такими я время не трачу.
    А до тех пор - дайте мне возможность самостоятельно распоряжаться моим временем - договорились? :)

    Во-вторых, готового кода - не будет.
    Я указал на суть проблемы -
    Вот и копайте, как это осуществить.
     
  11. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    хочет подтолкнуть к правильному решению, редко когда выкладывают готовые решения
     
  12. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Почему только о своём времени думаете?
    Распоряжаться Вашим временем не собирался!

    Если не умеете копать, то для чего говорить что лопату держать по другому требуется???

    Если Вы отвечаете не вникая в суть дела, то что об этом сказать?
     
  13. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Подталкивать нужно туда, где знаешь что хорошо!

    А толкать для того чтоб показывать свою силу - кому это нужно!?
     
  14. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    мммм, топик будет "урожайный"(с)Simpliest
    UPD:что, нет чтоле?)
     
  15. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Padaboo
    Нет, не будет.Я идиотами неумеющими думать не общаюсь :)

    doremidon
    Я ошибался. Я действительно впустую тратил свое время.
    Вы безнадежны.
     
  16. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Поясню, предоставил вначале 2 варианта вывода:
    1-й предусматривает обращение в БД для каждого прохода/вывода последующего ряда
    2-й изначально обращается один раз к БД и затем обрабатывает путём перебора все ряды


    Вопрос в более правильном применении тех ресурсов, которые предоставлены языком PHP или MySQL..
     
  17. Апельсин

    Апельсин Активный пользователь

    С нами с:
    20 мар 2010
    Сообщения:
    3.645
    Симпатии:
    2
    Так, первая фаза решения вопроса (Осмеять автора топа) - пройдена, гдето дальше должно последовать решение :))))
     
  18. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
  19. doremidon

    doremidon Активный пользователь

    С нами с:
    17 апр 2010
    Сообщения:
    9
    Симпатии:
    0
    Спасибо за информативный посыл .. )))

    Есть над чем поразмыслить..