Новости Joomla

0 Пользователей и 1 Гость просматривают эту тему.
  • 11 Ответов
  • 6240 Просмотров
*

boston

  • Захожу иногда
  • 495
  • 222 / 3
Больная для многих тема, решить которую можно и нужно  ;)
Суть проблемы: в Fireboard используются одни и теже запросы на каждую категорию/сообщение. Т.е. чем больше категорий и сообщений - тем больше SQL запросов. При это SQL запросы одинаковые и отличаются лишь по идентификаторам этих самых категорий или сообщений. Решение - делать по одному запросу на все категории и сообщения, результат записывать в глобальную переменную и для повтороного обращения использовать уже её, а не новый запрос.
Один расшевелить этого монстра вряд ли смогу, потому призываю всех к активному участию в этой ветке и к прикреплению топика.
Начну от своих первых изменений, запросов уменьшается не намного, но чем больше категорий и тем - тем заметнее. Потому прошу любить и тестировать.

ДАННЫЕ ИЗМЕНЕНИЯ ОПИСАНЫ ТОЛЬКО ДЛЯ ТЕСТИРОВАНИЯ И НУЖДАЮТСЯ В ПОДРОБНОМ ТЕСТИРОВАНИИ. ОТВЕТСТВЕННОСТИ ЗА ПОТЕРЯННЫЕ ИЛИ НЕПОЛУЧЕННЫЕ ДАННЫЕ НЕ НЕСУ.
Засучиваем рукова и в бой.
1. Файл: components/com_fireboard/template/default/listcat.php
1. Задача: Запись идентификаторов разрешённых категорий в таблицу сессий.
Решение от разработчиков: Все категории перебираются по циклу, если разрешена - то её идентификатор дописывается в таблиицу #__fb_sessions. Минус - чем больше категорий - тем больше запросов.
Было, 4 запроса:22UPDATE jos_fb_sessions SET allowed='1' WHERE userid=62
~
25UPDATE jos_fb_sessions SET allowed='1,2' WHERE userid=62
~
32UPDATE jos_fb_sessions SET allowed='1,2,6' WHERE userid=62
~
39UPDATE jos_fb_sessions SET allowed='1,2,6,7' WHERE userid=62

Моё решение: После перебора по циклу всех категорий переменная которая у разработчиков записывалась при каждом проходе содержит идентификаторы всех разрешенных категорий. Перенесём процедуру записи разрешённых идентификаторов после прохождения всего цикла - итог будет такой же, но запрос всего один на любое количество категорий. Посомтреть решение можно в приложенном файле, там есть все комментарии что и зачем изменяется.
Стало, 1 запрос:41UPDATE jos_fb_sessions SET allowed='1,2,6,7' WHERE userid=62

2. Задача: Выборка всех 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=and hold=and time>1190244594 group by thread
31
SELECT thread from jos_fb_messages where catid=and hold=and time>1190244594 group by thread
32
SELECT thread from jos_fb_messages where catid=and hold=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 запрос:28SELECT thread from jos_fb_messages where hold=and time>1190244594 group by thread

3. Файл: 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 запроса:~
66select idtitle from jos_fb_groups as gjos_fb_users as u where u.group_id g.id and u.userid62
67
select idtitle from jos_fb_groups as gjos_fb_users as u where u.group_id g.id and u.userid62
~

Моё решение: $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;
        }
}

Стало, один запрос:
~
66select idtitle from jos_fb_groups as gjos_fb_users as u where u.group_id g.id and u.userid62
~


В приаттаченном файле находятся оба изменённых файла с комментариями.
PS. Опыты проводились для авторизованного пользователя на Joostina RC1 и оригинальном Fireboard 1.0.3, тема - default и установленные стандартные тестовые данные. слева от SQL кода - порядковые номера, обращать внимания на них не стоит, они у каждого разные.

[вложение удалено Администратором]
« Последнее редактирование: 20.09.2007, 10:22:22 от boston »
Самая новая Joostina 1.3.0.5 UTF-8 stable | О найденных ошибках сообщаем | Расширения Joostina
*

smart

  • Администратор
  • 6478
  • 1318 / 15
  • Хочешь сделать хорошо — сделай!
Ну что ж, поддержу хорошее начинание Бостона. Взглянул бегло на код форума... Оптимизировать его и оптимизировать, очень много достаточно бестолкового кода, к примеру fireboard.php:


                
if ($fbConfig['cb_profile'])
                {
                    
$database->setQuery("update #__comprofiler set fbviewtype='_UE_FB_VIEWTYPE_FLAT' where user_id=$my->id");
                }
                
$database->setQuery("insert into #__fb_users (userid,view) values ('$my->id','flat')");


Ведь и ежу понятно, что независимо от условия, первый запрос выполнен никогда не будет, а время на это присвоение и проверку тратится...

Или вот кусок кода (правда это уже из модификации Адептуса):


 
/*************************** Adeptus hack start *******************************/
	
if (
$new_fb_user != 1)
    { 
//get session information, update last time timestamp.
        
$inactivePeriod = ($fbSession->lasttime)+1800;
        if (
$inactivePeriod $systime)
        { 
//grant them 30 minutes of inactivity; then recheck privileges and try to send them back where they came from
            
$database->setQuery("UPDATE #__fb_sessions SET allowed='na', readtopics='' where userid=$my->id");
            
$database->query();
            
setcookie("fboard_settings[prevvisit]"$fbSession->lasttimetime() + 31536000'/');
            
// do not reload the page if user is posting
            
if ($func != "post")
            {
               
/*echo '<script language="javascript">setTimeout("window.location.reload( true )",100);</script>'; */
	
	
	
	
	
//global $mosConfig_live_site;
	
	
	
	
	
//$database->setQuery("UPDATE #__fb_sessions SET lasttime=$systime where userid=$my->id");
	
	
	
	
	
//$database->query();
	
	
	
	
	
//mosRedirect($mosConfig_live_site.$_ENV["REQUEST_URI"]);
            
}
        }
        
$database->setQuery("UPDATE #__fb_sessions SET lasttime=$systime where userid=$my->id");
        
$database->query();
    } 
/************************** Adeptus hack end **********************/


Лучше бы заменить на:


 
/*************************** Adeptus hack start *******************************/
	
if (
$new_fb_user != 1)
    { 
//get session information, update last time timestamp.
        
$inactivePeriod = ($fbSession->lasttime)+1800;
        if (
$inactivePeriod $systime)
        { 
//grant them 30 minutes of inactivity; then recheck privileges and try to send them back where they came from
            
$database->setQuery("UPDATE #__fb_sessions SET allowed='na', readtopics='', lasttime=$systime where userid=$my->id");
            
$database->query();
            
setcookie("fboard_settings[prevvisit]"$fbSession->lasttimetime() + 31536000'/');
            
// do not reload the page if user is posting
            
if ($func != "post")
            {
               
/*echo '<script language="javascript">setTimeout("window.location.reload( true )",100);</script>'; */
	
	
	
	
	
//global $mosConfig_live_site;
	
	
	
	
	
//$database->setQuery("UPDATE #__fb_sessions SET lasttime=$systime where userid=$my->id");
	
	
	
	
	
//$database->query();
	
	
	
	
	
//mosRedirect($mosConfig_live_site.$_ENV["REQUEST_URI"]);
            
}
        } else {
        
$database->setQuery("UPDATE #__fb_sessions SET lasttime=$systime where userid=$my->id");
        
$database->query();
        }
    } 
/************************** Adeptus hack end **********************/

Это позволит в случае, если выполняется условие  $inactivePeriod < $systime сделать один запрос вместо двух.

Файл /sources/fb_karma.php:


                                $database
->setQuery('UPDATE #__fb_users SET karma_time=' $time ' WHERE userid=' $my->id '');
                                
$database->query();
                                
$database->setQuery('UPDATE #__fb_users SET karma=karma+1 WHERE userid=' $userid '');
                                
$database->query();


можно спокойно заменить на

                                $database
->setQuery('UPDATE #__fb_users SET karma_time=' $time ', karma=karma+1 WHERE userid=' $my->id '');
                                
$database->query();

Итого экономия 1 запрос при повышении кармы.

Аналогично:


                                $database
->setQuery('UPDATE #__fb_users SET karma_time=' $time ' WHERE userid=' $my->id '');
                                
$database->query();
                                
$database->setQuery('UPDATE #__fb_users SET karma=karma-1 WHERE userid=' $userid '');
                                
$database->query();


заменяем на


                                $database
->setQuery('UPDATE #__fb_users SET karma_time=' $time ', karma=karma-1 WHERE userid=' $my->id '');
                                
$database->query();


Еще один запрос выиграли...
*

smart

  • Администратор
  • 6478
  • 1318 / 15
  • Хочешь сделать хорошо — сделай!
Да... я все больше удивляюсь... ужас...

Файл /template/default/plugin/fbprofile/forummsg.php


        $query
            
"SELECT a.* , b.id as category, b.name as catname, c.hits AS 'threadhits' FROM #__fb_messages AS a, "
            
"\n #__fb_categories AS b, #__fb_messages AS c, #__fb_messages_text AS d"
            
"\n WHERE a.catid = b.id" "\n AND a.thread = c.id"
            
"\n AND a.id = d.mesid" "\n AND a.hold = 0 AND b.published = 1" "\n AND a.userid=$userid"\n AND (b.pub_access<='$group_id') ";
        
$database->setQuery($query);

        
$total count($database->loadObjectList());

Неужели для того, чтобы получить количество, необходимо выбрать из базы все записи, поместить в массив объектов, и только затем посчитать количество элементов массива ?

Намного проще ведь:



        $query
            
"SELECT COUNT(a.*) FROM #__fb_messages AS a, "
            
"\n #__fb_categories AS b, #__fb_messages AS c, #__fb_messages_text AS d"
            
"\n WHERE a.catid = b.id" "\n AND a.thread = c.id"
            
"\n AND a.id = d.mesid" "\n AND a.hold = 0 AND b.published = 1" "\n AND a.userid=$userid"\n AND (b.pub_access<='$group_id') ";
        
$database->setQuery($query);
        
$total $database->loadResult();


Хотя это тоже не очень верно, этот запрос фигово работать будет на новых версиях MySQL, там бы по уму надо сделать нормальные INNER JOIN...

Хм, так это просто стиль программирования этого компонента...

Файл template/default/plugin/myprofile/myprofile.php

                    $query 
"select thread from #__fb_subscriptions where userid=$my->id";
                    
$database->setQuery($query);
                    
$total count($database->loadObjectList());


А по-человечески это делается так:

                    $query 
"select count(thread) from #__fb_subscriptions where userid=$my->id";
                    
$database->setQuery($query);
                    
$total $database->loadResult();


Чуть ниже в том же файле (УЖОС):


                    $query 
"select thread from #__fb_favorites where userid=$my->id";
                    
$database->setQuery($query);

                    
$total count($database->loadObjectList());


Я начинаю понимать, почему этот форум сразу мне показался таким неповоротливым...
« Последнее редактирование: 20.09.2007, 12:03:28 от smart »
*

smart

  • Администратор
  • 6478
  • 1318 / 15
  • Хочешь сделать хорошо — сделай!
Еще один шедевр, файл /template/default/plugin/recentposts/recentposts.php


                
//find group id
                
$query "select gid from #__users where id=$my->id";
                
$database->setQuery($query);
                
$database->query();
                
$dse_groupid $database->loadObjectList();

                if (
count($dse_groupid)) {
                    
$group_id $dse_groupid[0]->gid;
                }
                else {
                    
$group_id 0;
                }


Ну во-первых, идентификатор группы пользователей доступен из поля переменной $my (т.е. как $my->gid), поэтому никакой нужды делать этот запрос нет. Во-вторых непонятно зачем сначала делать query(), а затем loadObjectList(), чтобы потом взять первый элемент массива...

Так что вся эта красота легко заменяется на:

$group_id $my->id $my->gid 0;

Дальше смотреть уже страшно - боюсь потерять веру в собратьев по профессии создавших этот продукт...
*

SloN

  • Осваиваюсь на форуме
  • 16
  • 1 / 0
  • Just try...
listcat.php редакция boston.
Не работает на FIREBOARD RE от adeptus.
Точнее работает, но не правильно.
1. Не правильно начинает отображаться шаблон форума.
2. Во всех темах показывает последее сообщение на 2 раньше от реального последнего сообщения.
class.fireboard.php редакция boston
Не обрабатывает группы пользователей.
« Последнее редактирование: 20.09.2007, 19:10:38 от SloN »
*

freedom

  • Захожу иногда
  • 318
  • 54 / 6
У меня заработала редакция Бостона
Версия: FireBoard ver.1.0.3 stable
Все работает: посты, темы, категории, форумы создаются и благополучно переносятся
Все отображается верно
Вроде как скорость загрузки выросла, но не значительно!

Редакция Бостона стоит здесь www.test.freedom-ru.net  (пока работает с отладкой так что можно посмотреть)
Время улучшения ситуации обратно пропорционально времени ее ухудшения. (например: Соседняя очередь всегда движется быстрее )
*

boston

  • Захожу иногда
  • 495
  • 222 / 3
SloN, Fireboard RE на базе первой ветки оригинального фоурма, а мои испралвения указаны для 1.0.3
freedom, это не моя редакция, это исправления которые еще и smart пишет. Что бы нормально тестировать надо базу побольше, сейчас эффект будет малозаметен ;)
Самая новая Joostina 1.3.0.5 UTF-8 stable | О найденных ошибках сообщаем | Расширения Joostina
*

freedom

  • Захожу иногда
  • 318
  • 54 / 6
Что бы нормально тестировать надо базу побольше, сейчас эффект будет малозаметен ;)

Судя по отладке было видно что кол-во запросов уменьшилось с 54 до 52
Время улучшения ситуации обратно пропорционально времени ее ухудшения. (например: Соседняя очередь всегда движется быстрее )
*

Sedoy

  • Давно я тут
  • 897
  • 87 / 10
  • Интересно,в какой кодировке пишут врачи?
Судя по отладке было видно что кол-во запросов уменьшилось с 54 до 52

круто однако :)
Что б правильно задать вопрос - нужно знать на него ответ!
FAQ по Joomla!
Где скачать шаблоны Joomla Статьи и обзоры Желаю Вам здоровья в личной жизни - живите долго и часто :)
*

Urich

  • Новичок
  • 6
  • 0 / 1
А я не могу понять, почему мой форум так много жрет, хостер аж пищит...
Форум синхронизирован с CB и стоит GroupJive
Кроме того используется компонент Frtbanners, включена поддержка мамботов
490 queries executed

Объясните что к чему !!!???!!!

[вложение удалено Администратором]
« Последнее редактирование: 06.02.2008, 01:19:58 от Urich »
*

Urich

  • Новичок
  • 6
  • 0 / 1
Применив ваши знания мне удалось сократить запросы с 490 до 474 - Господа, давайте доведем до ума этот форум!
Если у буржуев ручки кривые, давайте покажем им кузькину мать! !!!???!!!
*

Yomoto

  • Захожу иногда
  • 101
  • 2 / 0
Была очень большая нагрузка на сервер (около 1015 запросов к БД) после изменения кода,  приведен ниже, стало 150-170 запросов,  но все ранги и количество сообщений пользователей перестали отображаться. Может boston или smart смогли бы подсказать как вернуть утраченное с таким же количеством запросов к БД?
3. Файл: 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 запроса:~
66select idtitle from jos_fb_groups as gjos_fb_users as u where u.group_id g.id and u.userid62
67
select idtitle from jos_fb_groups as gjos_fb_users as u where u.group_id g.id and u.userid62
~

Моё решение: $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;
        }
}

Стало, один запрос:
~
66select idtitle from jos_fb_groups as gjos_fb_users as u where u.group_id g.id and u.userid62
~

Чтобы оставить сообщение,
Вам необходимо Войти или Зарегистрироваться
 

Как на FireBoard 1.0.4 вывести тег(и) Description

Автор krot

Ответов: 0
Просмотров: 2538
Последний ответ 01.11.2017, 19:48:59
от krot
Как сделать не активную ссылку в FIREBOARD?

Автор krot

Ответов: 0
Просмотров: 2699
Последний ответ 02.03.2017, 11:10:09
от krot
Kunena поверх FireBoard

Автор Benefactor

Ответов: 7
Просмотров: 5757
Последний ответ 31.01.2016, 23:19:17
от Marta
Хочу переехать на 1.5 джомлу. Что делать с FireBoard 2.0?

Автор mystique

Ответов: 7
Просмотров: 4706
Последний ответ 29.01.2016, 22:16:22
от Marta
FIREBOARD RE 2.0

Автор Adeptus

Ответов: 665
Просмотров: 264480
Последний ответ 20.07.2015, 18:13:53
от sayrus432