Главная » API Битрикс » CIBlockElement » CIBlockElement::GetList — оптимизация выборки в Битрикс

CIBlockElement::GetList — оптимизация выборки в Битрикс

Схема оптимизации выборки элементов инфоблока через CIBlockElement::GetList в Битрикс

CIBlockElement::GetList — самый частый источник тормозов на страницах с инфоблоками. Метод гибкий и прощает почти любой набор параметров, поэтому на нём легко написать код, который работает на тестовых 50 товарах и падает по таймауту на боевых 50 000. Разберём, какие параметры выборки решают проблему производительности.

Базовый вызов и его цена

<?php

$result = CIBlockElement::GetList(
    ['SORT' => 'ASC'],
    ['IBLOCK_ID' => 14, 'ACTIVE' => 'Y'],
    false,
    false,
    ['ID', 'NAME', 'PREVIEW_TEXT', 'PROPERTY_*']
);

while ($element = $result->GetNext()) {
    // ...
}

Каждый параметр в этом вызове по умолчанию тянет за собой больше данных, чем кажется. GetNext() без явного отключения подгружает ещё и PROPERTY_*, даже если пятый параметр выборки полей их не включал, — если не передать второй аргумент GetNext(false, false) явно в false для отключения этого поведения там, где свойства не нужны.

Отключение подсчёта элементов

Четвёртый параметр (постраничная навигация) по умолчанию считает общее количество найденных элементов отдельным запросом COUNT(*). Если постраничная навигация не выводится или общее число неважно — этот запрос лишний:

<?php

$result = CIBlockElement::GetList(
    ['SORT' => 'ASC'],
    ['IBLOCK_ID' => 14, 'ACTIVE' => 'Y'],
    false,
    ['nTopCount' => 20], // ограничение без подсчёта общего количества
    ['ID', 'NAME']
);

Нужна помощь с Битрикс?





    Явное отключение подгрузки свойств и файлов

    <?php
    
    while ($element = $result->GetNext(true, false)) {
        // первый true — не подгружать PROPERTY_*, если не указаны явно
        // второй false — не подставлять полный URL к файлам превью
    }

    Если свойства всё же нужны, но не все, а два-три конкретных — их стоит перечислить явно в пятом параметре (PROPERTY_COLOR, PROPERTY_SIZE) вместо маски PROPERTY_*, которая подгружает все привязанные свойства инфоблока целиком.

    Фильтрация по свойствам через отдельный индекс

    Фильтр вида ['PROPERTY_COLOR' => 'Красный'] в GetList требует, чтобы MySQL прошёлся по служебной таблице свойств инфоблока — на больших каталогах это заметно медленнее фильтра по обычным полям элемента. Если фильтрация по свойствам — основной сценарий использования раздела каталога (например, витрина с фильтром по характеристикам), эффективнее рассмотреть фасетный индекс умного фильтра, который для этого и предназначен, вместо прямого обращения к GetList на каждый запрос.

    Порядок сортировки и индексы

    Сортировка по PROPERTY_* полю не использует обычный индекс базы данных — она требует join с таблицей значений свойств и сортировку уже после соединения. Сортировка по штатным полям (SORT, ACTIVE_FROM, ID) работает быстрее, потому что эти поля хранятся прямо в таблице элементов и покрыты стандартными индексами модуля.

    Кеширование результата

    <?php
    
    use Bitrix\Main\Data\Cache;
    
    $cache = Cache::createInstance();
    $cacheId = 'catalog_top_' . $iblockId;
    $cacheDir = '/catalog/top/';
    
    if ($cache->initCache(3600, $cacheId, $cacheDir)) {
        $items = $cache->getVars();
    } elseif ($cache->startDataCache()) {
        $items = [];
    
        $result = CIBlockElement::GetList(
            ['SORT' => 'ASC'],
            ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'],
            false,
            ['nTopCount' => 12],
            ['ID', 'NAME', 'DETAIL_PAGE_URL']
        );
    
        while ($element = $result->GetNext(true, false)) {
            $items[] = $element;
        }
    
        $cache->endDataCache($items);
    }

    Для блоков, которые не меняются при каждом запросе (подборки, топ раздела, related-товары), кеш через Bitrix\Main\Data\Cache снимает нагрузку с базы полностью — GetList выполняется раз в час вместо на каждый визит.

    Частые ошибки

    • Маска PROPERTY_* там, где нужны одно-два свойства. Подгружает все привязанные свойства инфоблока лишним запросом.
    • Подсчёт общего количества при отключённой пагинации. Лишний COUNT(*) на каждый вызов без реальной надобности.
    • Сортировка по PROPERTY_* на большом каталоге. Требует join и сортировку без использования обычного индекса.
    • Отсутствие кеша для статичных блоков. Одна и та же выборка выполняется заново на каждый визит страницы.

    Итог

    Производительность GetList определяется не самим методом, а тем, что реально запрошено: отключение подсчёта количества там, где он не нужен, точный список свойств вместо маски, сортировка по штатным полям и кеш для стабильных блоков — вместе эти меры превращают тяжёлый запрос в лёгкий без изменения логики вывода.

    Нужна помощь с Битрикс?

    Исправим ошибку, доработаем сайт, ускорим Битрикс или поможем разобраться с проблемой.

    Услуги
    База знаний