Хак "Оптимизация вывода комментариев"

2072
Добрый день!

Сегодня с утра решил заняться оптимизацией запросов и обнаружил такую штуку - при выводе комментариев делается N запросов к БД(по количеству комментов) на предмет оценки комментария текущим пользователем. То есть если в статье 30 комментариев - то делается 30 запросов ,чтобы проверить оценивали вы его или нет, что не есть хорошо.

Данный хак (для версии инстанта 1.9) модифицирует запрос по получению комментариев и позволяет избавиться от ненужных N запросов.

Сразу скажу - не пугайтесь, что "много букав" - меняется всего 4 строки (две добавить и две изменить).
ВАЖНО: перед правкой обязательно сделайте копии файлов components/comments/model.php и components/comments/frontend.php


1. В файле components/comments/model.php находим строку
Код PHP:
public function getComments($target, $target_id, $cfg){
меняем на
Код PHP:
public function getComments($target, $target_id, $cfg,$user_id=0){
2. Далее в этой же функции меняем запрос с
Код PHP:
        $sql = "SELECT c.*,
                       IFNULL(v.total_rating, 0) as votes,
					   IFNULL(u.nickname, 0) as nickname,
					   IFNULL(u.login, 0) as login,
					   IFNULL(u.is_deleted, 0) as is_deleted,
					   IFNULL(p.imageurl, 0) as imageurl,
                       (NOW() < DATE_ADD(c.pubdate, INTERVAL {$cfg['edit_minutes']} MINUTE)) as is_editable
                FROM cms_comments c
                LEFT JOIN cms_ratings_total v ON v.item_id = c.id AND v.target = 'comment'
				LEFT JOIN cms_users u ON u.id = c.user_id
				LEFT JOIN cms_user_profiles p ON p.user_id = u.id
                WHERE c.target='$target' AND c.target_id=$target_id AND c.published=1
                ORDER BY c.pubdate ASC";


На
Код PHP:
        $sql = "SELECT c.*,
                       IFNULL(v.total_rating, 0) as votes,
					   IFNULL(u.nickname, 0) as nickname,
					   IFNULL(u.login, 0) as login,
					   IFNULL(u.is_deleted, 0) as is_deleted,
					   IFNULL(p.imageurl, 0) as imageurl,
                       (NOW() < DATE_ADD(c.pubdate, INTERVAL {$cfg['edit_minutes']} MINUTE)) as is_editable
                       ,(IF(r.id,1,0)) as is_voted
                FROM cms_comments c
                LEFT JOIN cms_ratings_total v ON v.item_id = c.id AND v.target = 'comment'
				LEFT JOIN cms_users u ON u.id = c.user_id
				LEFT JOIN cms_user_profiles p ON p.user_id = u.id
        LEFT JOIN cms_ratings r on ((r.item_id = c.id)and(r.target='comment')and(r.user_id = $user_id))
                WHERE c.target='$target' AND c.target_id=$target_id AND c.published=1
                ORDER BY c.pubdate ASC";
В запрос добавится две строки
Код PHP:
,r.id as is_voted
и
Код PHP:
LEFT JOIN cms_ratings r on ((r.item_id = c.id)and(r.target='comment')and(r.user_id = $user_id))
После этих правок запрос сразу вернет в поле is_voted "1" если посетитель голосовал за коммент и "0" если не голосовал.
3. В файле components/comments/frontend.php меняем строку
Код PHP:
$comments_list  = $model->getComments($target, $target_id, $cfg);
на
Код PHP:
$comments_list  = $model->getComments($target, $target_id, $cfg,$inUser->id);
4. и строку
Код PHP:
$comments[$next]['is_voted'] = ($comments[$next]['is_my'] || $inDB->rows_count('cms_ratings', 'item_id='.$comments[$next]['id'].' AND target=\'comment\' AND user_id='.$inUser->id, 1));
на
Код PHP:
$comments[$next]['is_voted'] = ($comments[$next]['is_my'] || $comments[$next]['is_voted']);
ВАЖНО: перед правкой обязательно сделайте копии файлов components/comments/model.php и components/comments/frontend.php
Модуль "Кто онлайн" (оптимизация + аякс) | Вывод "Ленты активности" как ВКонтакте
Теги: хак
Комментарии (29)
Def 3 марта 2012 в 13:57 0
в итоге сколько запросов получается?) один?)
SJen 3 марта 2012 в 14:06 0
Ну если раньше было 1+N, то сейчас просто 1.
Экономия N запросов. Это актуально для тех, у кого много комментариев к статьям (я тоже отношусь к этой группе)
Def 3 марта 2012 в 14:31 0
а у меня только такая строка есть:

Код PHP:
  public function getComments($target, $target_id, $cfg, $club_wall_view=0, $page=1){
SJen 3 марта 2012 в 14:32 0
эээ, версия какая инстанта?
Def 3 марта 2012 в 14:35 0
вроде 1.9
Malstein 3 марта 2012 в 15:09 +2
SJen а можно на ваш сайтик посмотреть?
SJen 3 марта 2012 в 15:49 +1
в личку кинул
Soul 3 марта 2012 в 16:42 +1
и я бы взглянул! Молодец! - пост за постом!+
Soul 3 марта 2012 в 17:01 +1
+++!
mrDON 3 марта 2012 в 17:19 0
не перестаешь радовать, +санул.
NIKITA 3 марта 2012 в 20:57 0
исчезли стили
my_projects\kristy.sytes.net\www\components\comments\frontend.php on line 156
обновил соmments на изначальный, нет результата
NIKITA 3 марта 2012 в 21:01 0
Parse error: syntax error, unexpected T_FOREACH in \my_projects\kristy.sytes.net\www\components\comments\frontend.php on line 156
SJen 3 марта 2012 в 21:27 0
Я так думаю, что стерли закрывающуюся скобку "}"
SJen 3 марта 2012 в 21:26 0
что-то не так вставили:)
Там же синтаксическая ошибка высветилась.

Если есть желание установить хак, закиньте свой frontend.php - помогу поставить.
Роман 3 марта 2012 в 22:25 0
+ за оптимизацию, это никогда не повредит.
на этом сайте часто вижу много полезных модификаций, и жалко, если их не будут включать в офф релиз

если можно скиньте сайт в личку :)
GarikKR 4 марта 2012 в 02:33 0
Спасибо большое за полезности!А можно тоже взглянуть одним глазком..
picaboo 4 марта 2012 в 14:16 0
Отличное начинание! Главное не останавливаться - там есть еще где пооптимизировать
ph3no 5 марта 2012 в 00:53 +1
SJen отличное решение, спасибо!
Еще бы проблему помогли бы решить с подвисанием сайта, когда включен вывод гостевых комментариев.
SJen 5 марта 2012 в 01:45 0
ну если конкретизируете проблемку, тогда возможно что подскажу.
пишите в личку, ну и сайт сразу кидайте.

Ну и вы хак этот поставьте, может проблема сама пропадет - нагрузка то реально снижается оооооочень сильно.
DimaGrr 10 марта 2012 в 07:43 0
Исправил, на 1.9 работает.
Coolmax 13 марта 2012 в 20:30 0
Вот бы ещё и поправленные файлики сразу выложили :)
SJen 13 марта 2012 в 20:46 0
поправленные файлики специально не выложил - у многих там уже измнений куча. И у меня кстати тоже - так что моя модификация файлов не нужна большинству.
veronika 23 апреля 2012 в 17:00 0
Подскажите в чем может быть проблема, после правки файлов пропадают комментарии т.е. пишется количество комментариев, но сами комментарии не выводятся, после замены исправленных файлов комментарии появляются.
SJen 23 апреля 2012 в 17:04 0
логично, что после возвращения файлов комментарии появляются)
Причина только в неправильной правке - что-то не туда вставили. Точнее нельзя сказать, не видя файлы.
veronika 23 апреля 2012 в 17:15 0
Тоже самое сделала на денвере, все работает?
SJen 23 апреля 2012 в 17:23 0
это вопрос?
у меня сайт одинаково ведет себя на денвере и на реальном сервере, у вас разве по-другому?)
Повторюсь, не видя файлы ничего более конкретно сказать нельзя - или очепятка или не туда копирнули что-то, это самая вероятная причина "неработы" на сервере.
veronika 23 апреля 2012 в 17:28 0
Скопировала файлы с сайта на денвере, результат тот-же, на сайте пропадают комментарии :(((
SJen 23 апреля 2012 в 17:37 0
кидайте файлы в архив, закидывайте на инстант в свои файлы и мне ссылочку в личку - посмотрю
по-другому ничего не решим)
Def 25 ноября 2012 в 12:43 0
а как на 1.10 с этим дела обстоят?