Тюним Tracker

Главные вкладки

Аватар пользователя AnNik AnNik 16 января 2010 в 13:42

Tracker - модулек малюсенький, но тяжеленный...
Даже в исходном коде видим комментик:
// TODO: These queries are very expensive, see http://drupal.org/node/105639

У меня Tracker начал ронять базу на неслабом дедике при таких объемах: около 10 тысяч юзеров, чуть больше 100тыс нод и 500тыс комментов.
Шаманство над my.cnf помогало весьма слабо... Пришлось покопаться в коде и поколдовать над запросами.

Итак.
1. Ну так как влазить в код ядра совсем некошерно, то первым шагом создаем папочку, к примеру, alttracker в sites/all/modules, копируем в нее все файлы модуля tracker, переименовываем их в alttracker.* и внутри них заменяем все вхождения словечка *tracker* на *alttracker*, *track* на *alttrack*.

2. Самое главное, ради чего все и затевалось. Облегчаем запросы.
Идем в alttracker.pages.inc и меняем там:

Строка 25
    $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) ORDER BY last_updated DESC';
Меняем на
        $sql = 'SELECT n.nid, n.title, n.type, n.changed, n.uid, (select name from {users} u where u.uid=n.uid) as name, GREATEST(n.changed, (select l.last_comment_timestamp from {node_comment_statistics} l where l.nid=n.nid)) AS last_updated, (select l.comment_count from {node_comment_statistics} l where l.nid=n.nid) as comment_count FROM {node} n WHERE n.status = 1 AND (n.uid = %d or exists (select c.nid from {comments} c where c.nid = n.nid and c.uid = %d and c.status = %d)) ORDER BY last_updated DESC';

Строка 27
    $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d)';
меняем на
    $sql_count = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status = 1 AND (n.uid = %d or exists (select c.nid from {comments} c where c.nid = n.nid and c.uid = %d and c.status = %d))';

Строка 29
    $result = pager_query($sql, 25, 0, $sql_count, COMMENT_PUBLISHED, $account->uid, $account->uid);
меняем на
    $result = pager_query($sql, 25, 0, $sql_count, $account->uid, $account->uid, COMMENT_PUBLISHED);

Строка 32
    $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 ORDER BY last_updated DESC';
меняем на
        $sql = 'SELECT n.nid, n.title, n.type, n.changed, n.uid, (select name from {users} u where u.uid=n.uid) as name, GREATEST(n.changed, (select l.last_comment_timestamp from {node_comment_statistics} l where l.nid=n.nid)) AS last_updated, (select l.comment_count from {node_comment_statistics} l where l.nid=n.nid) as comment_count FROM {node} n WHERE n.status = 1 order by last_updated desc';

На всякий случай комментим строки с db_rewrite_sql (строки 26, 28, 33, 35), если конечно они вам не особо нужны. Как эти запросы поведут себя, если их пропустить через db_rewrite_sql, не проверял:)

3. Идем в "Админ-Модули", отключаем Tracker и включаем наш AltTracker...

Итог:
1. База падать перестала;
2. Recent posts ("Последние сообщения" в меню) вместо 8-10 секунд отрабатывает за 2-3;
3. Track ("Следить" в профиле пользователя) - работает тоже заметно быстрее.

Осталась одна неясность: смысл проверки *** OR c.status IS NULL *** в первом запросе. У меня ни на одном из сайтов нет ни одной строки с comment.status IS NULL, в каких ситуациях он вообще может NULL-ом оказаться? Впрочем, даже если где-то и окажется, вряд ли это будет критично.

Дамы и господа, жду ваших критичных оценок. В первую очередь большая просьба глянуть незамыленным взглядом на предмет того, нет ли в оттюненых запросах каких-то ляпов:)

Комментарии