За последние 24 часа нас посетили 59126 программистов и 1811 роботов. Сейчас ищут 960 программистов ...

Помогите придумать обходной путь)

Тема в разделе "PHP для новичков", создана пользователем vl25, 25 сен 2010.

  1. vl25

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

    С нами с:
    30 янв 2009
    Сообщения:
    25
    Симпатии:
    0
    В общем есть функция рисовалки дерева категорий. Не суть важен её код сейчас. к каждой категории я вызываю функцию подсчета количества новостей в ней. Следовательно будет (колличество категорий)*(колличество запросов в функции)? у меня где - то 50 категори. следовательно 1 дерево жрёт 50 запросов как минимум при генерации. помогите советом.

    просто задумался об оптимизации, код писал когда только начинал кодить. функция подсчета:

    PHP:
    1. function countfile($category){
    2.         $s  = checkrazdel($category);
    3.         $dsds=parse_array($s);
    4.         $cc=mysql_num_rows(mysql_query("SELECT id FROM news WHERE category='$dsds' AND onsite='1'"));
    5.         return $cc;
    6.         }
    ах да, там еще функция проверки родительских категорий, это еще 1н запрос. время генерации всего сайта 0.03 сек.

    нужен совет
     
  2. ekip

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

    С нами с:
    11 авг 2009
    Сообщения:
    118
    Симпатии:
    0
    vl25 время генерации сайта 0.03 сек человеческий мозг не успеет заметить ;)
     
  3. ShamahN

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

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
  4. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    у меня такая же штука в админке, выводится сразу все рекурсивной функцией, тоже много запросов, сейчас буду кешировать все это дело куда нибудь:
    PHP:
    1. <?php
    2. public function buildTree($pid, $root = ''){
    3.         $childs = '';
    4.         $query = "SELECT *
    5.                  FROM `cat_tree`
    6.                  WHERE pid = $pid ORDER BY `name`";
    7.         $result = $this->registry['db']->query($query);
    8.  
    9.         while($row = $result->fetch_assoc()){
    10.  
    11.             $steps  = count(explode("/", $row['path']));
    12.             $childs = $this->buildTree($row['id'], $childs);
    13.            
    14.             $this->registry['view']->setPath('template/admin/childs.html');
    15.             if($steps >= 4){
    16.                 $this->registry['view']->setPath('template/admin/last_child.html');
    17.             }
    18.            
    19.             $this->registry['view']->setVar('id', $row['id']);
    20.             $this->registry['view']->setVar('name', $row['name']);
    21.             $this->registry['view']->setVar('pid', $row['pid']);
    22.             $this->registry['view']->setVar('childs', $childs);
    23.             $root  .= $this->registry['view']->prepare();
    24.             $childs = '';
    25.         }
    26.         return $root;
    27. }
    [​IMG]
     
  5. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    в общем сделал вот так:
    PHP:
    1. <?php
    2. class FileCache{
    3.     /*
    4.      *типа кэш
    5.      */
    6.     private $cache      = null;
    7.     /*
    8.      * время протухания
    9.      * в секундах
    10.      */
    11.     private $updateTime = null;
    12.     /*
    13.      * путь до файла с кэшем
    14.      */
    15.     private $path       = '';
    16.     /*
    17.      * нужно или не нужно кешировать
    18.      * bool
    19.      */
    20.     private $needCache  = null;
    21.     /*
    22.      * путь файла
    23.      * и время протухания
    24.      */
    25.     public function setCacheOtions($path, $updateTime = null){
    26.         $this->path       = $path;
    27.         $this->updateTime = $updateTime;
    28.         $this->needCache = $this->checkCache();
    29.     }
    30.     /*
    31.      * получить
    32.      */
    33.     public function getCache(){
    34.         $this->readCache();
    35.         return $this->cache;
    36.     }
    37.     /*
    38.      *сохранить
    39.      */
    40.     public function saveCache($data){
    41.         file_put_contents($this->path, $data);
    42.     }
    43.     /*
    44.      * возвращает bool
    45.      */
    46.     public function needCache(){
    47.         return $this->needCache;
    48.     }
    49.  
    50.     private function checkCache(){
    51.         if(!file_exists($this->path)){
    52.             touch($this->path);
    53.             chmod($this->path, 0644);
    54.             return true;
    55.         }
    56.  
    57.         if($this->updateTime != null){
    58.             $time       = time();
    59.             $rottenTime = filemtime($this->path) + $this->updateTime;
    60.             if($time > $rottenTime){
    61.                 return true;
    62.             }
    63.         }
    64.         return false;
    65.     }
    66.  
    67.     private function readCache(){
    68.         $this->cache = file_get_contents($this->path);
    69.     }
    70. }
    71. ?>
    PHP:
    1. <?php
    2. public function showCategory(){
    3.  
    4.         $cacher = new FileCache();
    5.         $cacher->setCacheOtions("cache/categorytree.html");
    6.        
    7.         if($cacher->needCache()){
    8.             $tree = $this->buildTree(1);
    9.             $cacher->saveCache($tree);
    10.         } else{
    11.             $tree = $cacher->getCache();
    12.         }
    13.         $this->loadContent($tree);
    14. }
    без
    с
    когда категорий будет 300-400 будет ощутимее думаю

    еше можно по времени
    PHP:
    1. <?php
    2. $cacher = new FileCache();
    3. $cacher->setCacheOtions("cache/test.html",10);
    4.  if($cacher->needCache()){
    5.       $data = time();
    6.        $cacher->saveCache($data);
    7.   } else{
    8.        $data = $cacher->getCache();
    9.   }
    10. echo $data;
    если файла нет то сам создаст
     
  6. vl25

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

    С нами с:
    30 янв 2009
    Сообщения:
    25
    Симпатии:
    0
    в общем после поста с товарищем написали функцию, которая сначала забирает все категории, гонит их в массив, потом парсит по конечной категории и выводит дерево. в общем на раздумие ушло 5 часов ( на 2 головы :) ). -100, примерно, запросов к базе. время генерации составляет 0,00606 среднее. в общем огромный контент тянется 3мя запросами.
     
  7. Padaboo

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

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    vl25
    дайте глянуть и структуру таблицы
     
  8. Volt(220)

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

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Если использовать Redundant Adjacency List, то можно взять дерево и подсчитать сумму по категории одним запросом.