Дата последнего изменения: 04.09.2025
Мелкие запросы, на первый взгляд, не сильно влияют (в относительной оценке) на работу сайта, если при этом на том же сайте есть какой-нибудь явно тяжелый кусок кода, связанный, например, с фильтрацией товаров, который по определению кешированию не поддается.
Достаточно часто в проектах многие используют вызов CIBlockElement::GetById. Простой, удобный метод, когда надо вытащить какое-то поле для элемента инфоблока. Но этот метод тянет все поля и все свойства элемента. В случае инфоблока с большим количеством свойств и большого числа посетителей на сайте этот простой запрос приводит к снижению производительности. А если таких запросов несколько десятков в различных result_modifier у разных компонентов? Оказывается, что в совокупности, несмотря на кеширование, эти вещи создают пиковые нагрузки в момент обновления кеша.
Если уж надо получить название элемента по ID, то лучше воспользоваться GetList с указанием конкретного вытаскиваемого поля элемента.
Соответственно, разница в скорости выполнения будет сильно зависеть от того, что именно надо вытащить, а потому сравнивать надо не просто два метода, а конкретную бизнес-логику конкретного сайта.
Также GetList позволяет выбрать сразу несколько записей, тогда как GetByID только одну.
Единственное преимущество GetById перед GetList с точки зрения разработчика состоит в том, что GetById можно просто вызвать и все. Прямое использование GetList требует определенной работы с кодом (создание массива параметров).
В большинстве случаев это делается в цикле, например в таком:
// неправильный вариант выборки, на каждый элемент делается дополнительный запрос
foreach($arResult['ITEMS'] as $ikey => $ival)
{
$avtorID = intval($ival['PROPERTIES']['AVTOR']['VALUE']);
if($avtorID > 0)
{
$rs = CIBlockElement::GetByID($avtorID);
while($ar = $rs->GetNext())
{
$arResulr['ITEMS'][$ikey]['AVTOR_INFO'][] = $ar;
}
}
}
но это неправильно. Такой цикл создает множество запросов, что снижает производительность.
Правильный вариант, это использовать один единственный запрос, в котором получать данные для требуемых элементов:
// правильный вариант, информация по авторам выбирается одним запросом и только нужная
$avtorID = array();
foreach($arResult['ITEMS'] as $ikey => $ival)
{
$aID = intval($ival['PROPERTIES']['AVTOR']['VALUE']);
if($aID > 0)
{
$avtorID[] = $aID;
}
}
$avtorID = array_unique($avtorID);
$rs = CIBlockElement::GetList(
array('ID' => 'ASC'),
array(
'IBLOCK_ID' => XX,
'ID' => $avtorID,
'ACTIVE' => 'Y'
),
false,
false,
array('ID', 'NAME', 'PREVIEW_PICTURE')
);
while($ar = $rs->GetNext())
{
$arResulr['AVTOR_INFO'][$ar['ID']] = $ar;
}
// правильный вариант,
// информация по книгам и связанная с ними информация по авторам выбирается одним запросом
$rs = CIBlockElement::GetList(
array('ID' => 'ASC'),
array(
'IBLOCK_ID' => YY,
'ACTIVE' => 'Y'
),
false,
false,
array(
'ID',
'NAME',
'PREVIEW_PICTURE',
'PREVIEW_TEXT',
'PROPERTY_AVTOR.NAME',
'PROPERTY_AVTOR.PREVIEW_PICTURE',
)
);
while($ar = $rs->GetNext())
{
$arResulr['ITEMS'][] = $ar;
}
Пример: Необходимо проверить для списка определенных пользователей, состоят ли они в заданной группе.
Типичный код:
foreach ($arSomeUser as $arUser)
{
$arGroups = CUser::GetUserGroup($arUser['ID']);
if(in_array(5, $arGroups))
{
// Делаем что-то
}
}
В этом случае у нас будет столько запросов, сколько пользователей в списке + один на выборку нужных пользователей из всех возможных (самый первый запрос).
Если в группе содержится мало пользователей, то правильнее будет использовать следующий подход:
$rsUser = $arUser->GetList(($by="ID"), ($order="desc"), array('ACTIVE' => 'Y', 'GROUPS_ID' => 5 ....))
while($arUser = $rsUser->GetNext())
{
// Делаем что то
}