Оптимизация умного фильтра для большого каталога 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Оптимизация умного фильтра для большого каталога 1С-Битрикс
Средний
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1322
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    915
  • 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
    663
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    811
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    710
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1043

Умный фильтр начинает деградировать при каталоге от 5 000 позиций. При 50 000+ он может отвечать 5–15 секунд на первый запрос и 1–3 секунды с кешем. Знакомая ситуация? Мы, как разработчики Битрикса с 7-летним опытом, сталкивались с этим десятки раз. У нас за плечами 150+ проектов, и мы гарантируем результат: снижение TTFB до 200 мс. Это не проблема алгоритма — это следствие того, что фильтр пересчитывает счётчики для каждого значения каждого свойства при каждом запросе. На реальном проекте с 30 свойствами и 50 000 товарами это тысячи запросов к БД за одно обращение.

Как устроен умный фильтр под капотом?

Компонент bitrix:catalog.smart.filter генерирует форму с асинхронной подгрузкой результатов через AJAX. Основные потребители ресурсов — COUNT-запросы для каждого значения свойства. Без оптимизации один запрос фильтра может инициировать до 200+ обращений к БД. Подробнее о платформе можно прочесть на Wikipedia.

Как диагностировать проблему?

Первый шаг — замер, а не угадывание. Включаем SQL-профилировщик:

// В начале скрипта
define('LOG_FILENAME', $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/log_filter.php');
$GLOBALS['DB']->ShowSqlStat = 'Y';

// После отработки компонента фильтра
$sqlLog = $GLOBALS['DB']->GetSqlTrack();
// Смотрим самые медленные запросы
usort($sqlLog, fn($a, $b) => $b['time'] <=> $a['time']);
var_dump(array_slice($sqlLog, 0, 10));

Типичная картина: 80% времени уходит на COUNT-запросы для пересчёта количества товаров по каждому значению свойства при применённом фильтре. Для глубокого понимания индексации MySQL рекомендую документацию.

Почему индексы критичны?

Наиболее значимое улучшение без изменения кода — правильные индексы. Умный фильтр активно использует таблицы b_iblock_element_prop_s* (простые свойства) и b_iblock_element_prop_m* (множественные).

-- Проверка существующих индексов
SHOW INDEX FROM b_iblock_element_prop_s15; -- 15 = ID инфоблока

-- Добавление составного индекса для фильтрации
CREATE INDEX idx_filter_prop ON b_iblock_element_prop_s15 (IBLOCK_ELEMENT_ID, PROPERTY_186, PROPERTY_187);

-- Для таблицы множественных свойств
CREATE INDEX idx_mult_prop ON b_iblock_element_property
    (IBLOCK_ELEMENT_ID, IBLOCK_PROPERTY_ID, VALUE_ENUM, VALUE_NUM);

После добавления индексов время ответа на каталоге 30 000 позиций снижается в 2–4 раза без изменения кода. Сравните подходы:

Подход Время первого запроса Время с кешем Сложность
Без оптимизации 8–15 с 2–3 с
Только индексы 1–2 с 0.5 с Низкая
Индексы + lazy load 0.2 с (TTFB) 0.3 с (счётчики) Средняя
Индексы + пред-агрегация 0.15 с 0.15 с Высокая

Обратите внимание: пред-агрегация даёт выигрыш в 50 раз по сравнению с живыми запросами на каталоге 150 000 товаров.

Как настроить кеширование фильтра?

$APPLICATION->IncludeComponent('bitrix:catalog.smart.filter', 'my_filter', [
    'IBLOCK_ID'         => 15,
    'SMART_FILTER'      => 'Y',
    'CACHE_TYPE'        => 'A',    // авто
    'CACHE_TIME'        => 3600,   // 1 час
    'CACHE_GROUPS'      => 'N',    // не разделять кеш по группам пользователей
    'LAZY_LOAD'         => 'Y',    // ленивая загрузка счётчиков
]);

LAZY_LOAD = 'Y' — счётчики загружаются отдельным AJAX-запросом после отрисовки страницы. Страница отвечает быстро, счётчики появляются через 200–400 мс.

Кеш тегами с инвалидацией

Агрессивное кеширование с инвалидацией при изменении каталога:

// Тег кеша привязан к инфоблоку
$taggedCache = \Bitrix\Main\Data\TaggedCache::instance();
$taggedCache->startTagCache('/catalog/filter/');

// Выполняем работу фильтра
// ...

$taggedCache->registerTag('iblock_id_' . CATALOG_IBLOCK_ID);
$taggedCache->endTagCache();

// При изменении элементов инфоблока — автоинвалидация:
// AddEventHandler('iblock', 'OnAfterIBlockElementUpdate', function($id, $fields) {
//     \Bitrix\Main\Data\TaggedCache::instance()->clearByTag('iblock_id_' . $fields['IBLOCK_ID']);
// });

Что даёт пред-агрегация счётчиков?

Для каталогов 100 000+ позиций — предварительная агрегация в отдельную таблицу через агент:

Код агента пред-агрегации
// Таблица для хранения предагрегированных данных
// CREATE TABLE b_custom_filter_counts (
//     iblock_id INT, property_code VARCHAR(50),
//     property_value VARCHAR(255), cnt INT,
//     updated_at DATETIME,
//     PRIMARY KEY (iblock_id, property_code, property_value(100))
// );

class FilterCountsAgent
{
    public static function recalculate(): string
    {
        $iblockId = CATALOG_IBLOCK_ID;
        $propertyCodes = ['BRAND', 'MATERIAL', 'COUNTRY'];

        foreach ($propertyCodes as $code) {
            // Подсчёт через прямой SQL
            $sql = "
                INSERT INTO b_custom_filter_counts
                    (iblock_id, property_code, property_value, cnt, updated_at)
                SELECT
                    e.IBLOCK_ID,
                    p.CODE,
                    pv.VALUE,
                    COUNT(DISTINCT e.ID),
                    NOW()
                FROM b_iblock_element e
                INNER JOIN b_iblock_element_property ep ON ep.IBLOCK_ELEMENT_ID = e.ID
                INNER JOIN b_iblock_property p ON p.ID = ep.IBLOCK_PROPERTY_ID
                INNER JOIN b_iblock_property_enum pv ON pv.ID = ep.VALUE_ENUM
                WHERE e.IBLOCK_ID = {$iblockId}
                  AND e.ACTIVE = 'Y'
                  AND p.CODE = '{$code}'
                GROUP BY e.IBLOCK_ID, p.CODE, pv.VALUE
                ON DUPLICATE KEY UPDATE cnt = VALUES(cnt), updated_at = VALUES(updated_at)
            ";

            \Bitrix\Main\Application::getConnection()->query($sql);
        }

        return 'FilterCountsAgent::recalculate();';
    }
}

Агент запускается каждые 15–30 минут. Счётчики в UI берутся из этой таблицы — не из live-запросов.

Уменьшение количества свойств в фильтре

Часто 30–40% свойств в фильтре никогда не используются. Анализ данных из систем аналитики:

  • Подключить события GTM на взаимодействие с каждым блоком фильтра
  • За 30 дней определить используемые vs неиспользуемые блоки
  • Убрать из фильтра блоки с менее чем 2% взаимодействий

На практике после такого аудита каталог с 28 свойствами в фильтре оставляет 12–15. Время генерации страницы снижается на 35–60% без технических изменений.

Из нашей практики: маркетплейс с 80 000 позиций

Маркетплейс стройматериалов. Фильтр отвечал 8–12 секунд на первый запрос, 2–3 с — с кешем. Индекс кеша сбрасывался при каждой смене цены поставщиком (десятки раз в день).

Решение в три этапа:

  1. Добавлены составные индексы на таблицы свойств — время 1,8 с без кеша
  2. Пред-агрегация счётчиков через агент каждые 20 минут — счётчики из таблицы за 5 мс
  3. Lazy load счётчиков — первый байт страницы через 180 мс, счётчики через 300 мс

Итого: с 8–12 с до 180 мс TTFB, счётчики за 300 мс.

Что входит в работу по оптимизации?

  • Аудит текущей конфигурации фильтра и SQL-профилирование
  • Создание и оптимизация индексов для таблиц свойств
  • Настройка кеширования (тегированное, lazy load)
  • Пред-агрегация счётчиков (при необходимости)
  • Рекомендации по сокращению неиспользуемых свойств
  • Документация по внедрению и поддержке
  • Консультация команды по дальнейшему развитию

Сроки и как начать

Аудит, добавление индексов и настройка кеширования — 1–2 рабочих дня. Полная оптимизация с пред-агрегацией, lazy load и аудитом используемых свойств — 3–5 рабочих дней.

Оценим ваш проект за 1 день. Закажите аудит фильтра — получите план оптимизации. Свяжитесь с нами, чтобы обсудить детали. Оставьте заявку на консультацию — проанализируем ваш каталог.