Больная для многих тема, решить которую можно и нужно
Суть проблемы: в Fireboard используются одни и теже запросы на каждую категорию/сообщение. Т.е. чем больше категорий и сообщений - тем больше SQL запросов. При это SQL запросы одинаковые и отличаются лишь по идентификаторам этих самых категорий или сообщений. Решение - делать по одному запросу на все категории и сообщения, результат записывать в глобальную переменную и для повтороного обращения использовать уже её, а не новый запрос.
Один расшевелить этого монстра вряд ли смогу, потому призываю всех к активному участию в этой ветке и к прикреплению топика.
Начну от своих первых изменений, запросов уменьшается не намного, но чем больше категорий и тем - тем заметнее. Потому прошу любить и тестировать.
ДАННЫЕ ИЗМЕНЕНИЯ ОПИСАНЫ ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ И НУЖДАЮТСЯ В ПОДРОБНОМ ТЕСТИРОВАНИИ. ОТВЕТСТВЕННОСТИ ЗА ПОТЕРЯННЫЕ ИЛИ НЕПОЛУЧЕННЫЕ ДАННЫЕ НЕ НЕСУ.Засучиваем рукова и в бой.
1. Файл: components/com_fireboard/template/default/listcat.php
1. Задача: Запись идентификаторов разрешённых категорий в таблицу сессий.
Решение от разработчиков: Все категории перебираются по циклу, если разрешена - то её идентификатор дописывается в таблиицу #__fb_sessions. Минус - чем больше категорий - тем больше запросов.
Было, 4 запроса:
22: UPDATE jos_fb_sessions SET allowed='1' WHERE userid=62
~
25: UPDATE jos_fb_sessions SET allowed='1,2' WHERE userid=62
~
32: UPDATE jos_fb_sessions SET allowed='1,2,6' WHERE userid=62
~
39: UPDATE jos_fb_sessions SET allowed='1,2,6,7' WHERE userid=62Моё решение: После перебора по циклу всех категорий переменная которая у разработчиков записывалась при каждом проходе содержит идентификаторы всех разрешенных категорий. Перенесём процедуру записи разрешённых идентификаторов после прохождения всего цикла - итог будет такой же, но запрос всего один на любое количество категорий. Посомтреть решение можно в приложенном файле, там есть все комментарии что и зачем изменяется.
Стало, 1 запрос:
41: UPDATE jos_fb_sessions SET allowed='1,2,6,7' WHERE userid=622. Задача: Выборка всех thread из таблицы #__fb_messages.
Решение разработчиков: При переборе категорий для каждой делается индивидуальный запрос.
$database->setQuery("SELECT thread from #__fb_messages where catid=$forumparent->id and hold=0 and time>$prevCheck group by thread");
$newPThreadsAll = $database->loadObjectList();
if (count($newPThreadsAll) == 0) {
$newPThreadsAll = array ();
}Было, 3 запроса:
30: SELECT thread from jos_fb_messages where catid=3 and hold=0 and time>1190244594 group by thread
31: SELECT thread from jos_fb_messages where catid=4 and hold=0 and time>1190244594 group by thread
32: SELECT thread from jos_fb_messages where catid=5 and hold=0 and time>1190244594 group by thread
Моё решение: создадим глобальныю переменную - массив со всеми необходимыми данными и будем его использовать.
Начало хака, $FBGLOBAL_newPThreadsAll - это глабальная переменная которая содержим все thread таблицы fb_messages ассоциированные с $forumparent->id*/
global $FBGLOBAL_newPThreadsAll;
if(!defined ('FB_newPThreadsAll')){
define('FB_newPThreadsAll',1);
$database->setQuery("SELECT thread from #__fb_messages where hold=0 and time>$prevCheck group by thread");
$newPThreadsAll = $database->loadObjectList();
foreach ($newPThreadsAll as $row){
$FBGLOBAL_newPThreadsAll["$forumparent->id "]=$row->thread;
};
}
if (count($FBGLOBAL_newPThreadsAll["$forumparent->id "]) == 0) {
$FBGLOBAL_newPThreadsAll["$forumparent->id "] = array ();
}Ниже по коду еще в 2х местах прописано использование новой переменной $FBGLOBAL_newPThreadsAll["$forumparent->id "].
Стало, 1 запрос:
28: SELECT thread from jos_fb_messages where hold=0 and time>1190244594 group by thread3. Файл: components/com_fireboard/class.fireboard.php
Решение разработчиков: Нормальная функция, единственный минус - при повтороном вызове она совершает одно и тоже действие и возвращает один резальтат.
function getFBGroupName($id) {
global $database;
$gr = '';
$database->setQuery("select id, title from #__fb_groups as g, #__fb_users as u where u.group_id = g.id and u.userid= $id");
$database->loadObject($gr);
if ($gr->id > 1) {
return $gr;
}
}Было, 2 запроса:
~
66: select id, title from jos_fb_groups as g, jos_fb_users as u where u.group_id = g.id and u.userid= 62
67: select id, title from jos_fb_groups as g, jos_fb_users as u where u.group_id = g.id and u.userid= 62
~Моё решение: $FBGLOBAL_getFBGroupName - глобальная переменная, которая всегда имеет одно значение.
При первом вызове функции она будет получаться из базы, при втором - уже просто возвращаться глобальное значение
function getFBGroupName($id) {
global $database,$FBGLOBAL_getFBGroupName;
if(isset($FBGLOBAL_getFBGroupName)) return $FBGLOBAL_getFBGroupName;
$gr = '';
$database->setQuery("select id, title from #__fb_groups as g, #__fb_users as u where u.group_id = g.id and u.userid= $id");
$database->loadObject($gr);
$FBGLOBAL_getFBGroupName=$gr;
if ($gr->id > 1) {
return $gr;
}
}Стало, один запрос:
~
66: select id, title from jos_fb_groups as g, jos_fb_users as u where u.group_id = g.id and u.userid= 62
~В приаттаченном файле находятся оба изменённых файла с комментариями.
PS. Опыты проводились для авторизованного пользователя на Joostina RC1 и оригинальном Fireboard 1.0.3, тема - default и установленные стандартные тестовые данные. слева от SQL кода - порядковые номера, обращать внимания на них не стоит, они у каждого разные.
[вложение удалено Администратором]