Yandex Metrika
sanches.free 18 просмотров

Ускорение Bitrix: catalog.section — урезать select в getElementList

.section (раздел «Ускорение» / витрина). На списке раздела тяжёлые поля вроде DETAIL_TEXT часто не нужны шаблону: их можно не тащить из БД, сузив массив $selectFields перед CIBlockElement::GetList.

Идея

Копируете шаблон компонента bitrix:catalog.section, подключаете класс компонента и объявляете наследника. В переопределённом getElementList() повторяете логику родителя до точки выборки и добавляете вычитку лишних полей через array_diff (в оригинале также снимают часть служебных ключей фильтра — ориентируйтесь на вашу версию ядра и состав $this->globalFilter).

Фрагмент: облегчённый select

use Bitrix\Iblock\Component\ElementList;

\CBitrixComponent::includeComponentClass('bitrix:catalog.section');

class GrainCatalogSection extends \CatalogSectionComponent
{
    protected function getElementList($iblockId, $products)
    {
        /* ... совпадает с родителем: navParams, filterFields, CATALOG_TYPE ... */

        $selectFields = $this->selectFields;
        $filterFields = $this->filterFields;
        if ($iblockId > 0) {
            $filterFields['IBLOCK_ID'] = $iblockId;
        }
        if (!empty($products)) {
            $filterFields['ID'] = $products;
        }

        $filter = array_merge($this->globalFilter, $filterFields);
        foreach (['CHECK_PERMISSIONS', 'MIN_PERMISSION', 'IBLOCK_LID', 'ACTIVE_DATE'] as $k) {
            unset($filter[$k]);
        }

        $selectFields = array_diff($selectFields, [
            'DETAIL_TEXT',
            'DETAIL_TEXT_TYPE',
            'TAGS',
            'DATE_ACTIVE_FROM',
            'DATE_ACTIVE_TO',
            'CREATED_BY',
            'MODIFIED_BY',
            'TIMESTAMP_X',
        ]);

        $iterator = \CIBlockElement::GetList(
            $this->sortFields,
            $filter,
            false,
            $this->navParams,
            $selectFields
        );
        $iterator->SetUrlTemplates($this->arParams['DETAIL_URL']);

        if ($this->isPaginationMode()) {
            $this->initNavString($iterator);
        }

        /* SetSectionContext как в родителе при ваших параметрах компонента */
        return $iterator;
    }
}

Уточнение: полный метод в ядре длиннее — перед копированием сверьте актуальную реализацию CatalogSectionComponent::getElementList в вашей версии: порядок проверок BigData, пагинации и контекста раздела менялся между релизами. Смысл правки — один: не выбирать колонки, которые список не рисует.

Замеры

Для сравнения «до/после» удобны метки \Bitrix\Main\Diag\Debug::startTimeLabel / endTimeLabel; отдельная заметка — тайм-лейблы. Не забывайте про композит и кеш компонента: выигрыш по SQL иногда заметен только под нагрузкой.

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии