Дата последнего изменения: 15.11.2023
Рассмотрим примеры, как можно улучшить производительность проекта.
Кеш очень важная составляющая производительности проектов. Чем эффективнее кешируем, чем кеш легче и быстрее, тем меньше ресурсов надо на поддержание проекта.
Но работа кеша может быть организована не совсем корректно, что приводит к проблемам производительности.Как неправильно:
// Класс кеширования пользователя с некорретным кешированием
class User
{
private $userData;
function __construct($userId = false)
{
if (!$userId)
{
global $USER;
$userId = $USER->GetID();
}
$cntStartCacheId = __CLASS__.'::'.__FUNCTION__.'|'.SITE_ID.'|'.$userId;
$cache = new \CXxxCache($cntStartCacheId.'sid0',3600,'user_data');
$this->userData = $cache->Init();
if (null == $this->userData)
{
$this->putUserData(array("ID"=>$userId));
$this->putUserData(\CUser::GetByID($userId)->Fetch());
$this->putUserData(array("DEPARTMENT" => $this->getDepartment()));
$cache->registerTag('USER_NAME_'.$userId);
$cache->set($this->userData);
}
}
}
Что не так в примере выше:
GetByIDFetchКак правильно:
class User
{
private $userData;
function __construct($userId = false)
{
if (!$userId)
{
global $USER;
$userId = $USER->GetID();
}
$cntStartCacheId = __CLASS__.'::'.__FUNCTION__.'|'.SITE_ID.'|'.$userId;
$cache = new \CXxxCache(
$cntStartCacheId.'sid0',
// увеличили время кеширования
604800,
// путь для ключей кеша сделали зависимым от $userID
'user_data/'.substr(md5($userId),2,2).'/'.$userId
);
$this->userData = $cache->Init();
if (null == $this->userData)
{
$this->putUserData(array("ID"=>$userId));
// Выбираем только нужные поля
$this->putUserData(\CUser::GetList(...)->GetNext(true, false));
$this->putUserData(array("DEPARTMENT" => $this->getDepartment()));
$cache->registerTag('USER_NAME_'.$userId);
$cache->set($this->userData);
}
}
}
GetByID на
GetList
Достаточно часто в проектах многие используют вызов CIBlockElement::GetById. Простой, удобный метод, когда надо вытащить какое-то поле для элемента инфоблока. Но этот метод тянет все поля и все свойства элемента. В случае инфоблока с большим количеством свойств и большого числа посетителей на сайте этот простой запрос приводит к снижению производительности.Fetch на GetNext(true, false).Пример на компоненте, который отображает дни рождения. Установлено большое время кеширования и добавлен дополнительный параметр, который сам компонент никак не отрабатывает и его не обрабатывает шаблон. Но так как в параметры подставлен date, то в 0 часов получим новый ключ у кеша данного компонента.
IncludeComponent(
"bitrix:intranet.structure.birthday.nearest",
"widget",
Array(
"CACHE_TYPE" => "A",
"CACHE_TIME" => "86450",
"DATE_FORMAT" => "j F",
"DETAIL_URL" => "#SITE_DIR#company/personal/user/#USER_ID#/",
"DEPARTMENT" => "0",
.....
"CACHE_DATE" => date('dmy')
)
);
В таком случае часто проставляют лишние параметры, что приводит к увеличению кеша. (например date без параметров приводит к обновлению кеша каждую секунду).
<?php
// Пример добавление в ключ кеша метки времени для корректного переключения кеша. Метка может быть и не из времени.
$cache = Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache(86450, '/some_key/'.date('myd').'/', '/some_dir/'))
{
$var = $cache->getVars();
}
else
{
// Получение данных
$cache->startDataCache();
$cache->endDataCache($var);
}
Процесс импорта обычно приводит к сбросу кеша. Если мы выгружаем большой объем данных - это занимает продолжительное время и дает большую нагрузку на боевом проекте. В ряде случаев этого можно избежать. В частности при работе с инфоблоками:
Индексация фасетного индекса также может быть отложена (т.е. отключена перед импортом и включена по окончании).
<?php // Отключение сброса тегированного кеша инфоблоков и пересчета фасетного индекса, во время импорта. Bitrix\Iblock\PropertyIndex\Manager::enableDeferredIndexing(); Bitrix\Catalog\Product\Sku::enableDeferredCalculation(); \CAllIBlock::disableTagCache($iblockID); // Импорт элементов \CAllIBlock::enableTagCache($iblockID); \CAllIBlock::clearIblockTagCache($iblockID); Bitrix\Catalog\Product\Sku::disableDeferredCalculation(); Bitrix\Catalog\Product\Sku::calculate(); Bitrix\Iblock\PropertyIndex\Manager::disableDeferredIndexing(); Bitrix\Iblock\PropertyIndex\Manager::runDeferredIndexing($iblockID);
Т.о. улучшение производительности достигается обновлением индексов и кеша только один раз, а не по количеству элементов.
|
if(defined('BX_COMP_MANAGED_CACHE'))
$GLOBALS['CACHE_MANAGER']->ClearByTag('iblock_id_'.$arParams['IBLOCK_ID']);