Оптимизация запросов к инфоблокам 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Оптимизация запросов к инфоблокам 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Оптимизация запросов к инфоблокам 1С-Битрикс

Инфоблок Битрикс — гибкий, но тяжёлый инструмент. Таблицы b_iblock_element, b_iblock_element_property, b_iblock_section, b_iblock_element_property_enum образуют реляционную структуру, которая при неаккуратных запросах порождает чудовищные планы выполнения. EXPLAIN запроса к списку 100 товаров с 5 свойствами нередко показывает перебор миллионов строк и несколько секунд выполнения. Для каталогов с активным трафиком это прямо влияет на TTFB и нагрузку на MySQL.

Проблемы старого API (CIBlockElement::GetList)

Старый API Битрикс (CIBlockElement::GetList) при запросе с PROPERTY_ фильтром генерирует запрос с JOIN к b_iblock_element_property для каждого свойства. При 5 свойствах в фильтре — 5 JOIN-ов. При этом API не позволяет явно управлять планом запроса.

Дополнительная проблема — параметр arSelect. Если передать "*" или упустить явный список полей, API запрашивает все поля, включая объёмные текстовые описания и ненужные метаданные. Для страницы каталога с 48 товарами это умножает объём передаваемых данных из БД в 3–5 раз.

Переход на D7 API (Iblock\ElementTable)

API D7 (\Bitrix\Iblock\ElementTable) предоставляет Query Builder с явным контролем select, filter, order, limit. Каждый запрос транслируется в SQL и может быть проанализирован через getQuery()->getSql() до выполнения.

Пример оптимального запроса для страницы каталога:

use Bitrix\Iblock\ElementTable;

$result = ElementTable::getList([
    'select' => [
        'ID',
        'NAME',
        'CODE',
        'PREVIEW_PICTURE',
        'IBLOCK_SECTION_ID',
    ],
    'filter' => [
        '=IBLOCK_ID'        => CATALOG_IBLOCK_ID,
        '=ACTIVE'           => 'Y',
        '=IBLOCK_SECTION_ID' => $sectionId,
    ],
    'order'  => ['SORT' => 'ASC', 'ID' => 'ASC'],
    'limit'  => 24,
    'offset' => $page * 24,
    'cache'  => ['ttl' => 3600],
]);

Explicit select без свойств — запрос только к b_iblock_element, без JOIN к b_iblock_element_property. Если свойства нужны для части товаров (например, только для тех, которые попали на страницу), они запрашиваются отдельным запросом по списку ID — это паттерн «запрос-по-ID-батчами» вместо N+1.

N+1 — главный враг производительности инфоблока

N+1 проблема в контексте Битрикс: получили список из 24 элементов, затем для каждого элемента в цикле вызываете CIBlockElement::GetProperty() или отдельный GetList для связанных данных. Итого: 1 запрос списка + 24 запроса свойств + 24 запроса связанных элементов = 49 запросов.

Решение — батчевая выборка:

// Получаем ID всех элементов
$ids = array_column($elements, 'ID');

// Один запрос для всех свойств
$propsResult = \CIBlockElement::GetPropertyValuesArray(
    $ids,
    CATALOG_IBLOCK_ID,
    ['CODE' => ['BRAND', 'COLOR', 'SIZE']]
);

Или через D7 с использованием \Bitrix\Iblock\ElementPropertyTable для выборки свойств списком ID.

Кеширование на уровне компонентов vs на уровне данных

Кеш компонента (файловый, через initCache) — грубый инструмент: кешируется весь HTML-фрагмент, инвалидируется по тегу IBLOCK_N. Для страниц с персонализацией или частыми обновлениями каталога это неудобно.

Кеширование на уровне данных через ManagedCache с гранулярными тегами (по разделу, по набору свойств) позволяет инвалидировать только затронутые записи. Накладные расходы — необходимость явно прописывать кеш в каждом месте обращения к данным.

Кейс: каталог стройматериалов, 45 000 SKU

До оптимизации: страница раздела каталога (48 товаров) — 1,8 с TTFB (без кеша), 340 ms с кешем. MySQL slow query log показывал: один запрос к списку товаров — 640 мс, второй запрос «похожих товаров» — 310 мс, суммарно 12 запросов на страницу.

Выявленные проблемы:

  • CIBlockElement::GetList с SELECT => "*" и PROPERTY_FILTER => [5 свойств]
  • N+1 в блоке «похожие товары»: запрос к каждому из 6 товаров отдельно
  • Запрос раздела с полным деревом дочерних разделов без ограничения уровня

Что сделали:

  • Переписали основной запрос на D7, explicit select (8 полей вместо всех)
  • Батчевый запрос свойств для блока «похожие товары»
  • Ограничение дерева разделов через параметр DEPTH_LEVEL и кеш с тегом раздела
  • Добавление индексов на b_iblock_element: составной по (IBLOCK_ID, IBLOCK_SECTION_ID, ACTIVE, SORT)

Результат: страница раздела (без кеша) — 380 мс TTFB, с кешем — 45 мс. Количество запросов к БД: 12 → 4. Нагрузка на MySQL снизилась, появилась возможность обслуживать в 3 раза больше одновременных пользователей без добавления мощностей.

Составные индексы для инфоблоков

Стандартные индексы Битрикс не покрывают все типичные выборки. Критичный индекс для каталога:

ALTER TABLE b_iblock_element
  ADD INDEX idx_iblock_section_active_sort
    (IBLOCK_ID, IBLOCK_SECTION_ID, ACTIVE, SORT);

Анализ текущих индексов через SHOW INDEX FROM b_iblock_element и EXPLAIN конкретных запросов из slow log — обязательный шаг перед добавлением.

Сроки

Этап Срок
Аудит запросов (slow log, Explain, панель Битрикс) 1–2 дня
Переработка критичных запросов (D7, batching) 3–7 дней
Индексы и настройка кеша 1–2 дня

На крупных проектах с большим количеством кастомных компонентов — до 3 недель.