Как упростить массив

Тема в разделе "Базы данных", создана пользователем vitek_gagra, 4 мар 2013.

Модераторы: latteo
  1. vitek_gagra

    vitek_gagra Создатель

    Регистр.:
    7 янв 2009
    Сообщения:
    47
    Симпатии:
    12
    Здравствуйте уважаемые форумчане.
    Подскажите как упростить массив, а то он сильно грузит сервер
    PHP:
    while ($b query_rw ("SELECT SQL_CALC_FOUND_ROWS n.*, c.`type_name` AS `cat_name`, COUNT(o.`hid`) AS `count_c` FROM (`newss` AS n, `art_parts` AS c) LEFT JOIN `news_comments` AS o ON (o.`hid` = n.`news_id`) WHERE c.`active` = 1 AND c.`type_id` = ".$_idc." AND n.`active` = 1 AND n.`part_id` = ".$_idc." GROUP BY n.`news_id` ORDER BY n.`news_date` DESC LIMIT ".$_offset.', '.$_limit)) {
                if (
    strval ($b['reviews']) == ''$b['reviews'] = 0;
               
                
    preg_match ('|^(\d{4})\-(\d{2})\-(\d{2})$|'$b['news_date'], $o);
                if (isset (
    $o[1]) && isset ($o[2]) && isset ($o[3])) $b['news_date'] = mktime (500$o[2], $o[3], $o[1]); else $b['news_date'] = time ();
               
                if (
    $b['img'] == ''$b['img'] = 'http://'.SITE_HOST.'/images/v2/nopic.jpg'; else $b['img'] = 'http://'.SITE_HOST.'/news_pics/'.$b['img'];
               
                
    $a[] = array (
                    
    'name' => $b['news_head'],
                    
    'text' => $b['news_anons'],
                    
    'date' => $b['news_date'],
                    
    'image' => $b['img'],
                    
    'url' => 'http://'.SITE_HOST.'/news/'.$_idc.'/'.$b['news_id'].'/',
                    
    'count_c' => $b['count_c'],
                    
    'count_v' => $b['reviews']
                );
               
                if (!isset (
    $_cname)) $_cname $b['cat_name'];
            }
    Этот массив делает выборку новостей из разделов в таблице art_parts выводит, на страницу раздела новостей список новостей из newss разбивает на страници и показывает сколько комментов (news_comments) у каждой новости.
    Движок самописный, программист кто писал движок отказывается переделывать говорит больше не занимается клиентскими сайтами и говорит что все хорошо написано, но у меня vps ложится, особенно когда показывается раздел архива новостей (1112 новостей).
    Я в этом не особо разбираюсь. Подскажите пожалуйста как его облегчить?!
     
  2. ВладимирТрой

    ВладимирТрой Постоялец

    Регистр.:
    29 янв 2013
    Сообщения:
    53
    Симпатии:
    19
    честно говоря вообще непонятно зачем здесь цикл.. здесь можно сделать все одной выборкой вместо того чтобы делать кучу запросов в цикле (как я понял идет получение по одной новости), это думаю уже значительно облегчит работу скрипта
    дальше можно с легкостью избавиться от left join'a - сделать отдельный один запрос и мержить данные на php
     
  3. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.517
    Симпатии:
    1.365
    Хотелось бы глянуть на файл работы с БД и в частности на функцию query_rw.
    На первый взгляд, код ощущается как бесконечный цикл, а с таким и самый мощный дедик не справится :)

    Чтобы оптимизировать запрос надо знать структуру таблиц - правильно расставленные индексы в десятки раз могут ускорить выполнение.

    Join сам по себе ничем не плох и если правильно применяется, то отработает быстрее нескольких запросов и обработки php-скриптом.
     
  4. vitek_gagra

    vitek_gagra Создатель

    Регистр.:
    7 янв 2009
    Сообщения:
    47
    Симпатии:
    12
    Добавил файловое кеширование и немного переписал запрос

    PHP:
    //Простое файловое кеширование - начало
           
            
    $filename 'cache/cache_' $_idc '_' $_offset '_' $_limit;
           
            if (
    is_file($filename) and filemtime($filename) > (time() - 3600)) {
               
                
    $array unserialize(file_get_contents($filename));
           
                
    $a $array['a'];
               
                
    $b $array['b'];
               
                
    $_cname $array['_cname'];
           
                
    $num_rows $array['_num_rows'];
           
            }
           
            if (!
    $array) {
                
    $query mysql_query("select * from newss where active=1 and part_id=".$_idc." order by news_date desc;");
                
    $num_rows = (int)mysql_num_rows($query);
                while (
    $b query_rw ("SELECT * FROM (`newss` AS n, `art_parts` AS c) WHERE c.`active` = 1 AND c.`type_id` = ".$_idc." AND n.`active` = 1 AND n.`part_id` = ".$_idc." GROUP BY n.`news_id` ORDER BY n.`news_date` DESC LIMIT ".$_offset.', '.$_limit)) {
               
                
    $query mysql_query("select type_name from art_parts where active=1 and type_id=".$_idc.";");
                
    $res mysql_fetch_array($query);
               
                    if (
    strval ($b['reviews']) == ''$b['reviews'] = 0;
                   
                    
    preg_match ('|^(\d{4})\-(\d{2})\-(\d{2})$|'$b['news_date'], $o);
                    if (isset (
    $o[1]) && isset ($o[2]) && isset ($o[3])) $b['news_date'] = mktime (500$o[2], $o[3], $o[1]); else $b['news_date'] = time ();
                   
                    if (
    $b['img'] == ''$b['img'] = 'http://'.SITE_HOST.'/images/v2/nopic.jpg'; else $b['img'] = 'http://'.SITE_HOST.'/news_pics/'.$b['img'];
                   
                    
    $a[] = array (
                        
    'name' => $b['news_head'],
                        
    'text' => $b['news_anons'],
                        
    'date' => $b['news_date'],
                        
    'image' => $b['img'],
                        
    'url' => 'http://'.SITE_HOST.'/news/'.$_idc.'/'.$b['news_id'].'/',
                        
    'count_c' => $b['count_c'],
                        
    'count_v' => $b['reviews']
                    );
                   
                    if (!isset (
    $_cname)) $_cname $res['type_name'];
                }
               
                
    file_put_contents($filenameserialize(array('a' => $a'b' => $b'_cname' => $_cname'_num_rows' => $num_rows)));       
               
            }
     
            
    //Простое файловое кеширование - конец
           
            
    if (count ($a) > 0) {
     
                
    $_count = (int) $_res[0];
                
    $_pages ceil ($num_rows/$_limit);
               
                if (
    $_pages 1$_data['loop']['navi'] = prepare_navigation ($_pages$_page$_data['url_clear']);
            }
    Не знаю правильно или нет, но работает :) Стал гораздо быстрее работать сайт и не грузит сервер.
    Осталось сделать подсчет комментариев. Вот это не знаю как правильно сделать.
    Вот таблица комментариев к новостям. в hid указывается id новости

    Код:
    CREATE TABLE IF NOT EXISTS `news_comments` (
      `cid` int(10) unsigned NOT NULL auto_increment,
      `hid` int(11) unsigned default NULL,
      `aid` int(10) unsigned default NULL,
      `tblname` varchar(250) character set utf8 default NULL,
      `usr_login` varchar(250) character set utf8 default NULL,
      `usr_mail` varchar(250) character set utf8 default NULL,
      `usr_mess` text character set utf8,
      `likenotlike` int(10) default '0',
      `alllikenotlike` int(10) default '0',
      `add_date` datetime default NULL,
      `checked` int(10) unsigned default NULL,
      `active` int(1) unsigned default NULL,
      `ip` bigint(20) unsigned NOT NULL,
      PRIMARY KEY  (`cid`)
    )
    Вот таблица новостей. news_id это id новости, part_id это id раздела новостей.

    Код:
    CREATE TABLE IF NOT EXISTS `newss` (
      `news_id` int(11) unsigned NOT NULL auto_increment,
      `part_id` int(10) unsigned default NULL,
      `news_head` varchar(200) default NULL,
      `news_anons` text,
      `news_mess` text,
      `news_descr` varchar(200) default NULL,
      `news_keys` varchar(200) default NULL,
      `news_date` date default NULL,
      `img` varchar(250) default NULL,
      `aslink` int(1) unsigned default NULL,
      `active` int(1) unsigned default NULL,
      `comment` int(1) unsigned NOT NULL default '1',
      `reviews` int(11) unsigned default NULL,
      `autor` varchar(30) NOT NULL default 'Admin',
      `isto4nik` varchar(250) NOT NULL,
      `isto4nik_name` varchar(30) NOT NULL,
      PRIMARY KEY  (`news_id`)
    )
    А вот таблица разделов новостей. type_id это id раздела новостей

    Код:
    CREATE TABLE IF NOT EXISTS `art_parts` (
      `type_id` int(10) unsigned NOT NULL auto_increment,
      `type_name` varchar(250) character set cp1251 default NULL,
      `order_num` int(10) default NULL,
      `active` int(1) unsigned default NULL,
      `gl` int(1) unsigned NOT NULL default '0',
      PRIMARY KEY  (`type_id`)
    )
    Вот ссылка на страницу где используется тот массив Перейти по ссылке
    Под количеством просмотров показывалось количество комментариев в новости, но из за того что тяжелый был запрос пришлось пока убрать, но хотелось бы сделать что бы показывало, но не знаю как составить запрос для подсчета комментов..
     
  5. uNknownMark

    uNknownMark

    Регистр.:
    22 сен 2007
    Сообщения:
    393
    Симпатии:
    169