Оптимизация 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
Источник: sandev.pro

Просмотров:

Добавить комментарий