Уменьшение запросов в БД (микрохак))

+38
2.83K
Привет всем !

Это будет полезно тем у кого обычный хостинг,
при этом динамичный сайт с выводом модулей на страницах.
Есть возможность снизить нагрузку на БД, убрав немного запросов для
незарегистрированных пользователей (которых наверное у всех большинство))



Как мы знаем, у всех модулей есть возможность кеширования на определенный срок.
Это очень существенно может снизить нагрузку на БД и ускорить процесс генерации странички .

Я настроил у себя кеширование примерно от 3 до 30 минут на разные модули,
попутно отслеживая ко-л во запросов и время генерации.
На главной удалось снизить запросы с ~100 до ~55.

Сейчас кеш для гостей работает так же как и для зарегистрированных пользователей.
Т.е. БД дергается постоянно на проверку жизни кеша и если, что — обновляет.
Это и понятно, сайт должен оставаться динамичным ..

Но можно немного и схитрить )

Можно сделать так, что бы незарегистрированный пользователь никогда не дергал базу запросами
о жизни кеша, тем самым ускорить генерацию и еще снизить запросы в базу.

Логика хака такова :
Для Незарегистрированного пользователя не будет запросов в базу о жизни кеша.
Соответственно и модули не будут лишний раз дергать базу ..
Кеш в обычном режиме будет обновляться только при посещении сайта зарегистрированным пользователем.
И соответственно это обновление увидят и гости на сайте, т.е. сайт по прежнему остается динамичным !

Это, например мне, позволило дополнительно снизить запросы на главной с 55 до 36 для гостей..
т.е. на каждую сотню гостей, только на на главной страничке, убрано более 1900 запросов к БД !)
Время жизни кеша на это никак не влияет, можно хоть 1 минуту ставить ..

Делается все в файле core/classes/page.class.php
Нужно найти функцию: public function printModules($position)
и в ней вот эти строки :

  1.  
  2. if( $mod['is_external'] ){
  3. if (file_exists($modulefile)){
  4. require_once $modulefile;
  5. if ($mod['cache'] && $inCore->isCached('module', $mod['mid'], $mod['cachetime'], $mod['cacheint'])){
  6. $modulebody = $inCore->getCache('module', $mod['mid']);
  7. $callback = true;
  8. } else {
  9. $config = $inCore->yamlToArray($mod['config']);
  10. $inCore->cacheModuleConfig($mod['module_id'], $config);
  11. $callback = $mod['content']($mod['module_id']);
  12. $modulebody = ob_get_clean();
  13. if($mod['cache']) { $inCore->saveCache('module', $mod['mid'], $modulebody); }
  14. }
  15. }
  16. }
  17.  
и заменить на :

  1.  
  2. if($mod['is_external']){
  3. if (file_exists($modulefile)){
  4. require_once $modulefile;
  5. if (!$inUser->id){
  6. if ($mod['cache']){$modulebody = $inCore->getCache('module', $mod['mid']);$callback = true;}
  7. else {$config = $inCore->yamlToArray($mod['config']);$inCore->cacheModuleConfig($mod['module_id'], $config);
  8. ob_start();$callback = $mod['content']($mod['module_id']);$modulebody = ob_get_clean();}}
  9. else {
  10. if ($mod['cache'] && $inCore->isCached('module', $mod['mid'], $mod['cachetime'], $mod['cacheint'])){$modulebody = $inCore->getCache('module', $mod['mid']);
  11. $callback = true;}
  12. else {$config = $inCore->yamlToArray($mod['config']);$inCore->cacheModuleConfig($mod['module_id'], $config);
  13. ob_start();$callback = $mod['content']($mod['module_id']);$modulebody = ob_get_clean();
  14. if($mod['cache']) {$inCore->saveCache('module', $mod['mid'], $modulebody);
  15. }}}}}
  16.  

Ну и как обычно… Не забудьте сделать резервную копию и тд и тп…
glasses
+2
picaboo picaboo 12 лет назад #
Спасибо за идею :)

кстати у вас на морде <!-- 1.5993(37) -->
а если войти в блоги <!-- 0.0747(63) -->

что-то всеравно тормозит, запросов в два раза меньше, а время генерации в 20 раз больше
0
KS KS 12 лет назад #
На главной модули из iMaps выводятся ...
А их к сожалению кешировать нельзя .. Поэтому и время генерации такое ..
Если их отключить то будет как в блогах .

Но честно говоря 1.5 что то совсем много . У меня больше 0.4 не было на главной ..
Если есть возможность , попробуйте пару раз обновить страничку , посмотрите сколько покажет .
+1
picaboo picaboo 12 лет назад #
обновлял, лучший результат <!-- 0.3683(35) --> но обычно в районе секунды и выше
+1
KS KS 12 лет назад #
Нашел причину ...
Это как я и думал модули мапса. Больше всего грузит новостной , запрос в нем тяжелый идет на вывод всего. буду его ковырять на днях )
Хотя если в мапсе включить режим одного города, то он летать начинает..
Получается все связано с детектом города и отсевом вывода после этого.
Спасибо Вам и Sjen за бдительность !

Попробовал с отключением всего Мапса , главная стала - <!-- 0.0470(32) -->
+1
letsgo letsgo 12 лет назад #
Плюс за хак.
0
fact fact 12 лет назад #
а что реально помогает?
0
KS KS 12 лет назад #
Помогает !
У меня запросов без кеша около 100 на главной должно бы быть ..
С кешем 55 минимум (пока он живет)
С хаком (вне зависимости жизни кеша) 36-37
+1
universe universe 12 лет назад #
на счет хака, если страницу никто из зарегистрированных пользователей не посещал в течении 2 недель. То гости будут видеть кешь 2-х недельной давности?
0
KS KS 12 лет назад #
Да.
В этом и логика. Контент в основном обновляют зарегистрированные пользователи.
+2
universe universe 12 лет назад #
а если сделать, что то в виде кнопки обновить кешь. И весь вешь на сайте автоматом обновляется
0
KS KS 12 лет назад #
Можно сделать , но какой смысл? Это нужно только если у вас контент могут добавлять незарегистрированные пользователи ..
А если какой либо модуль например парсит инфо, то его можно просто не кешировать и он будет обновлятся и у гостей )
+1
googlebot googlebot 12 лет назад #
есть уже такая кнопка - поищите в блогах
+1
universe universe 12 лет назад #
знаю эту кнопку но дело в том, если очиститься кешь то модули которые не открывали зареганные, то у гостей пусто будет или все таки пойдет запрос на создание кеша?
+1
Дмитрий Дмитрий 12 лет назад #
Супер элементарно и эффективно, но...
Не работает вот с этим модулем: http://instantcms.ru/blogs/moi-blozhek/modul-socialnye-zakladki.html
Гости не видят иконок социалок, только сам блок.
У зареганных всё хорошо.
+1
Дмитрий Дмитрий 12 лет назад #
Хотя, похоже, что это особенности ИЕ.
ИЕ8 залогиненный юзер тоже не видит эти закладки и лог из браузера:

Сведения об ошибке на веб-странице

Агент пользователя: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB7.3; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C)
штамп времени: Wed, 9 May 2012 00:32:52 UTC


Сообщение: '0' - есть null или не является объектом
Строка: 18
Символ: 1
Код: 0
URI-код: .../modules/mod_soccontent/bookmarks.js

В строке 18 находится такой код:
btn+='<a href="http://'+services[0]+'" target=_blank><img src="'+dir+services[1]+'" alt="Добавить в '+services[2]+'" title="Добавить в '+services[2]+'" style="border:0;padding:0;margin:0 4px 0 0;"></a>';}

Ох уж этот ИЕ - ВСЕГДА проблемы ))
0
KS KS 12 лет назад #
Этот хак вообще ни как не влияет на работоспособность модуля .
Попробуйте отключить кеширование блока соц закладок.
Заметил такую вещь , что если включать кеш для модулей у которых js прописан прямо внутри кода ,
вылазиют всякие глюки ..
У меня так же с было с модулем вывода новостей на js , решил сунуть код внутрь , а его "понесло"
по экрану )..
0
SJen SJen 12 лет назад #
а каким образом был "прописан прямо внутри кода"?
в tpl шаблоне через "add_js file"?
+1
Дмитрий Дмитрий 12 лет назад #
Может кто подскажет, что это же за трабла с ИЕ8? :)
http://made-in-handmade.com - вот здесь модуль BOOKMARK
0
KS KS 12 лет назад #
Нет , модуль без tpl, вся работа внутри module.php ,
Скрипт мизерный , я его легко вставил внутрь и он заработал , но
как то криво .. причем функционал в норме а дизайн перекосило в ИЕ.

Это наверно как в случае с вашим кешированием и ИЕ ,
скорее всего что то похожее ..
+1
Дмитрий Дмитрий 12 лет назад #
По умолчанию кеш был выключен. Включал/выключал ничего не изменилось. Но да ладно, фиг с ним с этим ИЕ8, наверное это менее 10% пользователей, не страшно. Просто в качестве информации, вдруг решение найдётся )
0
s21 s21 12 лет назад #
обновлял, лучший результат <!-- 0.3683(35) --> но обычно в районе секунды и выше

а где показывается тот результат? тоже хочу проверить свой сайт...
+1
KS KS 12 лет назад #
Самый простой вариант это включить "режим отладки" в настройках сайта, и после обновления странички внизу будет видно время генерации и запросы к базе ..
Только после тестов отключить не забудьте )
0
s21 s21 12 лет назад #
Спасибо!
0
Alon Alon 10 лет назад #
Это действует на движок 1,10,1 ?
0
KS KS 10 лет назад #
да , если функция полностью такая.
У меня на 1.10 стоит, полет нормальный
0
Alon Alon 10 лет назад #
Как с вами можно связаться? мне нужно срочно решить эту проблему
0
Александр I Александр I 10 лет назад #
Код для версии ICMS 1.10.1
В файле ../core/classes/page.class.php
В функции public function printModules($position)
найти (стр. 432-456):
Код PHP:
  1. // Отдельный модуль
  2. if( $mod['is_external'] ){
  3. if (file_exists($modulefile)){
  4. require_once $modulefile;
  5. // Если есть кеш, берем тело модуля из него
  6. if ($mod['cache'] && cmsCore::isCached('module', $mod['id'], $mod['cachetime'], $mod['cacheint'])){
  7. $mod['body'] = cmsCore::getCache('module', $mod['id']);
  8. $callback = true;
  9. } else {
  10. $config = cmsCore::yamlToArray($mod['config']);
  11. $inCore->cacheModuleConfig($mod['id'], $config);
  12. $callback = $mod['content']($mod['id']);
  13. $mod['body'] = ob_get_clean();
  14. if($mod['cache']) { cmsCore::saveCache('module', $mod['id'], $mod['body']); }
  15. }
  16. }
  17. }
и заменить на:
Код PHP:
  1. // Отдельный модуль
  2. if($mod['is_external']){
  3. if (file_exists($modulefile)){
  4. require_once $modulefile;
  5. if (!$inUser->id){
  6. if ($mod['cache']){
  7. $mod['body'] = cmsCore::getCache('module', $mod['id']);
  8. $callback = true;
  9. } else {
  10. $config = cmsCore::yamlToArray($mod['config']);
  11. cmsCore::cacheModuleConfig($mod['id'], $config);
  12. $callback = $mod['content']($mod['id']);
  13. $mod['body'] = ob_get_clean();}
  14. } else {
  15. if ($mod['cache'] && cmsCore::isCached('module', $mod['id'], $mod['cachetime'], $mod['cacheint'])){
  16. $mod['body'] = cmsCore::getCache('module', $mod['id']);
  17. $callback = true;
  18. } else {
  19. $config = cmsCore::yamlToArray($mod['config']);
  20. cmsCore::cacheModuleConfig($mod['id'], $config);
  21. $callback = $mod['content']($mod['id']);
  22. $mod['body'] = ob_get_clean();
  23. if($mod['cache']) {
  24. cmsCore::saveCache('module', $mod['id'], $mod['body']);
  25. }
  26. }
  27. }
  28. }
  29. }
0
Александр Александр 10 лет назад #
а это работает со всеми 1.10.* ? 3-4 например

Еще от автора

Похожие в Универсальном каталоге (хак для 1.x)
На одном из сайтов, где используется универсальный каталог для вывода различных товаров и тд, появилась необходимость сделать вывод похожих при просмо
Плагин  'Вставить фото из своих альбомов' (ver.1.10* & &uarr;)
Добрый день! Заметил одну особенность..
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.