Помощь Оптимизировать вывод последних комментариев

Тема в разделе "DLE", создана пользователем IIya, 18 апр 2011.

Информация :
Актуальная версия DataLife Engine 11.3
( Final Release v.11.3 | Скачать DataLife Engine | Скачать 11.3 demo )
Нужно ли обновляться | Как обновиться | Изменения в шаблонах
> Нет русских символов <
[Приватная тема DLE (Все подробности в ЛС к модератору раздела)]

Версии 11.2 и ниже - уязвимы!

Локализации | F.A.Q. | Внешний вид
Правила раздела | Правила форума
Обсуждение хайда карается баном!
В каждом сообщении указывайте версию DLE, которого они касаются!
Статус темы:
Закрыта.
Модераторы: killoff
  1. IIya

    IIya Создатель

    Регистр.:
    20 дек 2006
    Сообщения:
    26
    Симпатии:
    2
    DLE 9.0 Изменил вывод последних комментариев, - добавил функцию вывода всех последних комментариев из новостей указанного пользователя.
    Вывод информации выводится по ссылке _http://site.ru/index.php?do=lastcomments&author=Username
    Всё было бы замечательно, но код очень сильно грузит mysql и в итоге сайт не загружается.
    Привожу код lastcomments.php:
    PHP:
    <?php
    if( ! defined'DATALIFEENGINE' ) ) {
        die( 
    "Hacking attempt!" );
    }
    $userid intval$_REQUEST['userid'] );
    $_SESSION['referrer'] = $_SERVER['REQUEST_URI'];
    $allow_list explode','$user_group[$member_id['user_group']]['allow_cats'] );
    $where = array ();
    if( 
    $userid ) {
            
    $where[] = PREFIX "_comments.user_id='$userid'";
            
    $user_query "do=lastcomments&amp;userid=" $userid;
    } else
    {
    if( isset( 
    $_REQUEST['author'] ) ) $author = @$db->safesqlstrip_tagsurldecode$_REQUEST['author'] ) ) ); else $author "";
            if (
    $author!=="")
            {
            
    $user_query "do=lastcomments&amp;author=" $author;
            
    $where[] = PREFIX "_post.autor='$author'";
            }
            else
            
    $user_query "do=lastcomments";
    }
    if( 
    $allow_list[0] != "all" ) {
        
    $join "LEFT JOIN " PREFIX "_post ON " PREFIX "_comments.post_id=" PREFIX "_post.id ";
        if( 
    $config['allow_multi_category'] ) {
            
    $where[] = PREFIX "_post.category regexp '[[:<:]](" implode'|'$allow_list ) . ")[[:>:]]'";
        } else {
            
    $where[] = PREFIX "_post.category IN ('" implode"','"$allow_list ) . "')";
        }
    } else {
        
    $join "";
    }
    if( 
    $config['allow_cmod'] ) {
        
    $where[] = PREFIX "_comments.approve='1'";
    }
    if( 
    count$where ) ) {
        
    $where implode" AND "$where );
        
    $where "WHERE " $where;
    } else
        
    $where "";
    if( 
    $userid ) {
            
    $sql_count "SELECT COUNT(*) as count FROM " PREFIX "_comments " $join $where;
    } else
    {
            if (
    $author!=="")
            {
            
    $sql_count "SELECT COUNT(*) as count FROM " PREFIX "_post," PREFIX "_comments " $join $where;
            }
            else
            
    $sql_count "SELECT COUNT(*) as count FROM " PREFIX "_comments " $join $where;
    }
    $row_count $db->super_query$sql_count );
    if( 
    $row_count['count'] ) {
        include_once 
    ENGINE_DIR '/classes/comments.class.php';
        
    $comments = new DLE_Comments$db$row_count['count'], $config['comm_nummers'] );
        
    $comments->query "SELECT " PREFIX "_comments.id, post_id, " PREFIX "_comments.user_id, " PREFIX "_comments.date, " PREFIX "_comments.autor as gast_name, " PREFIX "_comments.email as gast_email, text, ip, is_register, name, " USERPREFIX "_users.email, news_num, " USERPREFIX "_users.comm_num, user_group, reg_date, signature, foto, fullname, land, icq, " USERPREFIX "_users.xfields, " PREFIX "_post.title, " PREFIX "_post.date as newsdate, " PREFIX "_post.alt_name, " PREFIX "_post.category, " PREFIX "_post.flag FROM " PREFIX "_comments LEFT JOIN " PREFIX "_post ON " PREFIX "_comments.post_id=" PREFIX "_post.id LEFT JOIN " USERPREFIX "_users ON " PREFIX "_comments.user_id=" USERPREFIX "_users.user_id " $where " ORDER BY id desc";
        
    $comments->build_comments('comments.tpl''lastcomments' );
        
    $comments->build_navigation('navigation.tpl'false$user_query);        
    } else {
        
    msgbox$lang['all_info'], $lang['err_last'] );
    }
    ?>
    Тобишь в стандартном коде было изменено:
    1. изменение данных для запроса
    PHP:
    if( $userid ) {
            
    $where[] = PREFIX "_comments.user_id='$userid'";
            
    $user_query "do=lastcomments&amp;userid=" $userid;
    } else
    {
    if( isset( 
    $_REQUEST['author'] ) ) $author = @$db->safesqlstrip_tagsurldecode$_REQUEST['author'] ) ) ); else $author "";
            if (
    $author!=="")
            {
            
    $user_query "do=lastcomments&amp;author=" $author;
            
    $where[] = PREFIX "_post.autor='$author'";
            }
            else
            
    $user_query "do=lastcomments";
    }
    2. изменение запроса для нужной функции:
    PHP:
    if( $userid ) {
            
    $sql_count "SELECT COUNT(*) as count FROM " PREFIX "_comments " $join $where;
    } else
    {
            if (
    $author!=="")
            {
            
    $sql_count "SELECT COUNT(*) as count FROM " PREFIX "_post," PREFIX "_comments " $join $where;
            }
            else
            
    $sql_count "SELECT COUNT(*) as count FROM " PREFIX "_comments " $join $where;
    }
    Прошу помочь оптимизировать код, ибо сам ничего в этом не шарю... А функция очень нужная!
     
  2. IIya

    IIya Создатель

    Регистр.:
    20 дек 2006
    Сообщения:
    26
    Симпатии:
    2
    Что и мыслей никаких нет? Может знаете где подскажут? Видимо нужно грамотных программистов...
    У меня только приходит на ум создать дополнительное поле в таблице comments, где будет записываться имя автора новости, а потом уже будет проще выводить нужные результаты из comments не рыская в post.

    Ещё говорят в таких случаях разделяют запросы, например отдельно ищут в comments и отдельно в post... Но как это разделение осуществляется не имею понятия.
     
  3. Juri

    Juri

    Заблокирован
    Регистр.:
    5 окт 2007
    Сообщения:
    1.065
    Симпатии:
    197
    не надо пытаться сделать это один запросом сделайте в 2 3...

    А вообще не до конца понял, что вы хотите вывести последние комментарии пользователя?
     
  4. IIya

    IIya Создатель

    Регистр.:
    20 дек 2006
    Сообщения:
    26
    Симпатии:
    2
    Я понимаю что запросы нужно разделить, но не имею понятия как это сделать в данном случае. Совершенно не понимаю.

    Вот пример: Пользователь(N) пишет новости... На эти новости приходят комментарии от других пользователей. Дек вот этот скрипт выводит все комментарии на все новости пользователя(N).
     
  5. killoff

    killoff CD тихо, и не DVD меня ;)

    Moderator
    Регистр.:
    13 май 2008
    Сообщения:
    2.167
    Симпатии:
    796
    а чем не устраивает стандартная возможнность /index.php?do=lastcomments&userid=1? Ссылку на последние комментарии пользователя можно найти в профиле пользователя, если конечно она не была удалена из шаблона.
     
  6. Juri

    Juri

    Заблокирован
    Регистр.:
    5 окт 2007
    Сообщения:
    1.065
    Симпатии:
    197
    писать запрос честно говря лень, но могу посоветовать собрать ид всех новостей пользователя одним запросом, а потом другим вытянуть все комментарии
    будет что то типа

    PHP:
    $sql $db->query("SELECT id FROM post WHERE author LIKE 'autor'");
                while(
    $row $db->get_array($sql))
                {
                    
    $idlist .=$row[id].",";
                }
                
    $sqlcomment $db->query("SELECT * FROM comments WHERE post_id IN ('$idlist')");
                while(
    $rowcomments $db->get_array($sqlcomment))
                {
                    echo 
    '...';
                }
    ну вот как то так, естественно нужно допилить, но я думаю суть понятна.

    К тому же почитайте про предикат IN очень полезная штука
    _http://sql-ex.ru/help/select2.php#pr_in
     
  7. IIya

    IIya Создатель

    Регистр.:
    20 дек 2006
    Сообщения:
    26
    Симпатии:
    2
    Человек дорогой, я уже дважды описал чем отличается моё изменение от стандартной функции. Читайте внимательней!
    К стати стандартная функция конечно осталась на месте.
    Сегодня попробовал оптимизировать функцию с использованием предикат IN... Запрос получился такого вида:
    PHP:
    SELECT COUNT(*) as count FROM dle_comments LEFT JOIN dle_post ON dle_comments.post_id=dle_post.id WHERE dle_post.autor IN ('$author')
    Уже стало по легче, выдаёт выполнение запроса за 0.5-1.3 сек. и выполнение скрипта за 0.9-2.0 сек. По моему всё равно тяжеловато... Чуть позже попробую разделить запросы как ты написал выше.
    Может у кого есть ещё варианты?
     
  8. IIya

    IIya Создатель

    Регистр.:
    20 дек 2006
    Сообщения:
    26
    Симпатии:
    2
    Если создавать массив для Предикат IN с помощью:
    PHP:
    $idlist .=$row[id].",";
    То массив получается такого вида:
    PHP:
    SELECT COUNT(*) as count FROM dle_comments WHERE dle_comments.post_id IN ('1146829596,1146829665,1146829643,1146829676,')
    И результат получается не правильный, так как в конце массива остаётся лишняя запятая! Как от неё избавиться?
     
  9. Juri

    Juri

    Заблокирован
    Регистр.:
    5 окт 2007
    Сообщения:
    1.065
    Симпатии:
    197
    отрежте, для этого есть функция substr
     
  10. IIya

    IIya Создатель

    Регистр.:
    20 дек 2006
    Сообщения:
    26
    Симпатии:
    2
    Эммм чёто я почитал мануалы по этой функции и не понял как её можно применить.
    Наглядный пример имеется? =)
     
Статус темы:
Закрыта.