Оптимизация DLE для DLE

Оптимизация DLE

Оптимизация DLE

Периодически у меня появлялось желание как-то оптимизировать DLE в плане программной части. Но все никак руки не доходили или желания не было.
Хочу немного поделиться своими решениями в плане оптимизации запросов к БД в DLE.
Не так давно проводил ряд работ по оптимизации сайта. Монитор нагрузки показывал загрузку процессора на 70-90%. Тут и top не нужно смотреть, чтобы понять что проблема в mysql.
Специально для этой задачи был написан относительно простенький модуль, который вел лог всех запросов в бд и записывал статистику. На скриншотах ниже - результат сбора статистики за один вечер, время 20:40 - 22:20.
Вот по результатам этих данных (и не только) проведем небольшой анализ и постараемся оптимизировать по максимуму.
Внимание: Если у вас DLE 13.x, то вместо ручного внесения изменений вам нужно использовать утилиту управления плагинами, как ею пользоваться описано в инструкции.


1. Общие рекомендации
В самую первую очередь строго обязательно рекомендуется отключить функцию "Поддержка публикации новостей на еще не наступившую дату". Этот параметр очень много дает.
Так же рекомендую отключить все другие не используемые модули, типа topnews, календарь и т.п.


2. not detected
Оптимизация DLE

Думаю тут все и так ясно, за исключением последней колонки GC (group count). Это количество - сколько раз выполнялся этот запрос.
Данные запросы появляются при обращении к не существующим категориям. В принципе не критично, но блин, зачем выполнять 2 запроса если априори известно, что в результате ничего не будет и быть не должно.
Решение:
Открыть файл engine/modules/show.short.php
Найти строку:
if( $allow_active_news ) {

Выше нее вставить:
if ($do == 'cat' && !(int)$category_id) {
	$allow_active_news = false;
}



3. SELECT COUNT(*) as count FROM dle_post
Оптимизация DLE

Просто посмотрите на эти числа, а главное количество этих запросов. Разумеется кеширование включено, но...
Вот еще мне человек писал, цитата от хостера:
При проверке, мы видим, что в момент обновления указанной Вами ссылки, в базу ***** данных поступает запрос вида :
SELECT COUNT(*) as count FROM dle_post WHERE category regexp '[[:<:]](702|703|704|706|707|709|710|711|712|713|714|715|716|717|718|719|720|721|723|724|725|726|729|730|731|732|733|734|735|737|738|739|740|741)[[:>:]]' AND approve=1;

При ручном выполнении данного запроса, мы и вправду наблюдаем затрату времени 2.70 sec

Решение:
Если у вас DLE 11.1 или младше, то потребуется установить хак Количество новостей в категории
Для более старших версий - в настройках необходимо включить параметр "Осуществлять подсчет количества новостей в категориях"
Открыть файл engine/modules/show.short.php
Найти строку (первую):
		$count_all = $db->super_query( $sql_count );

Выше нее вставить:
		if ($do == 'cat' && isset($cat_info[(int)$category_id]['newscount'])) {
			$count_all = array(
				'count' => (int)$cat_info[$category_id]['newscount']
			);
		} else 

Данный хак полностью исключит вышеуказанные проблемные запросы. Но именно только для категорий. Хотя по сути в категориях-то как раз и выполняется наибольшее количество подобных запросов.


4. Мысли по п.3
Запросы мы убрали, все хорошо. Но вот вопрос, почему этих запросов так много при включенном кешировании.
Тут немножко дело зависит от версии DLE. К примеру в версии 10.6 и младше кешировались только первые 5 страниц навигации, остальные вообще без кеша. Затем это число было увеличено до 10 страниц, так продолжалось вплоть до 11.2. И уже начиная с 11.3 и до актуальной версии это число можно вручную указывать в настройках - "Количество страниц сайта, которое необходимо кешировать при показе кратких публикаций".
Это правильный шаг, но пользоваться этим параметром нужно тоже с умом. Если у вас к примеру 10-20 категорий, то можно кешировать и 20-30 страниц, получится 200 - 600 файлов кеша, что вполне приемлемо.
Но если у вас много категорий, то количество кешируемых страниц оптимально как раз около 10.

Немного отвлекся от основной темы данного раздела, а именно почему этих запросов так много? И ответ достаточно прост - кеширование. А именно очистка кеша. Добавление нового комментария, оценка в рейтинге - оба эти действия полностью сносят кеш всех страниц с отображением короткой новости и блоков custom. Не слабо так, один лайк и кеш обнулен.
Многое зависит от сайта и желаний владельца сайта - нужно ли вам, чтобы каждое действие тут же было видно в короткой новости или может в короткой новости вообще не отображается ни рейтинг ни количество комментариев. Так что я просто приведу инструкцию, а вносить эти правки или нет - уже решать вам.
Открыть файл engine/modules/addcomments.php
Найти строку:
clear_cache( array( 'news_', 'comm_'.$post_id, $cprefix ) );

или
clear_cache( array( 'news_', 'rss', 'comm_'.$post_id, $cprefix ) );

Заменить на:
clear_cache( array( 'comm_'.$post_id, $cprefix ) );

Таким образом, при добавлении комментария будет очищен только кеш текущей новости и сами комментарии.

Открыть файл engine/ajax/rating.php
Найти строку (2шт):
clear_cache( array( 'news_', $cprefix ) );

или
clear_cache( array( 'news_', 'rss', $cprefix ) );

Заменить на:
clear_cache( array( $cprefix ) );

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


5. order="RAND()"
RAND() - зло.
Но если вам очень уж хочется использовать эту сортировку, но я приведу простую аналогию.
К примеру новости - это стальные шарики весом 10г каждый. У вас есть 100 шариков и вы хотите выбрать из них 10 случайных.
Засыпаете их в ведро и колотите пока не выпадут 10шт. Это не сложно, всего-то 1кг шариков + вес ведра.
Теперь у вас 2000 шариков (новостей), вы хотите так же выбрать из них 10 случайных. Повторяем процедуру, только теперь уже нужно активно и быстро месить 20кг, что не так-то и просто, но пока вполне реально.
И совсем уж для понимания, когда в среднем на том же киносайте порядка 30тыс новостей, получается что месить уже нужно 300 кг. Думаю суть ясна.
Но чтобы закрепить понимание, добавим 100 посетителей, когда каждый заходит раз в 1 секунду и просит из 10кг шариков выбрать один любой. И причем каждый посетитель хочет свой уникальный шарик (типа без кеша). В один прекрасный момент наш работяга метусильник (mysql) пошлет все в ж**пу и пойдет на перекур (Server has gone away). И возможно сам не захочет возвращаться.
Если уж хотите использовать rand - делайте это с умом. Либо не заставляйте его каждую секунду метусить 300кг (кеширование результатов выборки, тут кстати может помочь Ручной кеш), либо пусть месит до 1кг (ограничить изначальную выборку, по дате или другим параметрам, чтобы итоговое максимальное количество новостей было небольшим). А еще лучше комбинировать оба метода.

На этом, пожалуй, пока все. Спасибо что дочитали до конца (если это так :)), буду рад вашим комментариям и предложениям.

С уважением,
Олег Александрович a.k.a. Sander
Комментарии: (11)
  1. foto
    VIP 4 июля 2018 22:00 #
    Применимо ко всем версиям?
    0
    1. foto
      Администратор 4 июля 2018 22:02 #
      На 10.1 проверял, для более ранних не проверял. Возможно и подойдет.
      0
      1. foto
        VIP 4 июля 2018 22:23 #
        На сколько снизилась нагрузка у Вас после всех манипуляций?
        0
        1. foto
          Администратор 4 июля 2018 22:34 #
          Нельзя сказать однозначно.
          Там было несколько однотипных сайтов и реальную проблемную нагрузку создавал запрос от страниц поиска по доп.полям - /xfsearch/... (актеры, режиссеры и т.п)
          Там использовался старый алгоритм, где поиск выполнялся по xfields LIKE '%слово%' который собственно и создавал огромную нагрузку. Страниц нереально много и наличие кеша не играло вообще никакой роли.

          Вы можете легко попробовать у себя и провести замеры. Все эти изменения не являются необратимыми.
          0
  2. foto
    Гость 5 июля 2018 15:24 #
    Доброе время. А можно подогнать модуль и инструкцию для модуля Custom-Cache для DLE 13. А то после установки модуля, блок вообще перестаёт кешироваться и обновляется при каждой перезагрузке страницы. Пробовали ставить и через модули и через правку файлов, ни один вариант не работает, всё делал строго по инструкции, блок так и обновляется постоянно.
    0
    1. foto
      Администратор 5 июля 2018 15:28 #
      1. Почему вы задаете этот вопрос здесь, а не в теме модуля
      2. Техподдержка только по указанным контактам.

      PS. В dle 13 необходимо вносить правки только посредством утилиты управления плагинами.
      0
  3. foto
    Гость 10 июля 2018 05:10 #
    Есть один нюанс на DLE 12, в show.short.php вы указали найти строчку и выше вставить нужный код
    $count_all = $db->super_query( $sql_count );

    у меня нашло 2 такие строчки, выше которой ставить?

    Сам код выглядит так
    
    		$count_all = $db->super_query( $sql_count );
    		if($news_found AND !$count_all['count']) {
    			$db->query("ANALYZE TABLE `" . PREFIX . "_post`, `" . PREFIX . "_post_extras`");
    			$count_all = $db->super_query( $sql_count );
    		}
    
    0
    1. foto
      Администратор 10 июля 2018 11:08 #
      Перед первой
      0
  4. foto
    VIP 14 июля 2018 20:04 #
    Sander, указанные правки будут все работать, если их оформить через плагины? ))
    0
    1. foto
      Администратор 14 июля 2018 20:05 #
      Да, конечно.
      Разве что для п3. нужно будет в поле "Найти" вставить не одну строку, а сразу 2:
      		$count_all = $db->super_query( $sql_count );
      		
      		if($news_found AND !$count_all['count']) {

      И уже перед этим кодом вставлять.
      +1
      1. foto
        VIP 14 июля 2018 20:39 #
        Спасибо, проверю.
        0
Добавить комментарий
  • Логин
  • E-mail (не обязательно)
Повторите рисунок:
antibot
© Sander-Development. 2009-2018.
При копировании, ссылка на источник обязательна.