Мы не раз видели, как стандартный catalog.smart.filter в 1С-Битрикс превращает навигацию по каталогу с 50 000+ SKU в мучение. Каждый клик по чекбоксу вызывает отдельный SQL-запрос к b_iblock_element с полным пересчётом — ждать 800–1500 мс приходится при каждом изменении. Пользователь видит «зависший» интерфейс и уходит. Ситуация усугубляется, если в каталоге используется модуль catalog с привязкой к b_catalog_price и множественными свойствами через b_iblock_element_property. В результате фильтрация становится узким местом, а каждый обмен с 1С — триггером для сброса кеша и нового простоя.
Обычное решение — включить SHOW_PRODUCTS_COUNT в компоненте — только усугубляет проблему: каждый раз выполняется дорогой агрегатный запрос. Мы предлагаем другой подход: перенести подсчёт в денормализованную таблицу и строить AJAX-механику вокруг неё. Это даёт ускорение в 10–15 раз, а экономия на серверных ресурсах может достигать 150 000 руб. в месяц при каталоге от 100 000 SKU.
стандартный умный фильтр тормозит?
Компонент bitrix:catalog.smart.filter при включённом параметре SHOW_PRODUCTS_COUNT выполняет агрегирующий запрос вида:
SELECT COUNT(DISTINCT BE.ID)
FROM b_iblock_element BE
INNER JOIN b_iblock_element_property BEP ON BE.ID = BEP.IBLOCK_ELEMENT_ID
WHERE BE.IBLOCK_ID = ? AND BE.ACTIVE = 'Y' AND BEP.IBLOCK_PROPERTY_ID = ? AND BEP.VALUE = ?
При десяти одновременно выбранных свойствах фильтра это превращается в цепочку JOIN-ов или подзапросов, которые MySQL выполняет без использования составных индексов. EXPLAIN показывает тип ALL или index вместо ref — полный перебор таблицы.
Вторая проблема — инвалидация кеша. Стандартный тег кеша bitrix:catalog сбрасывается при любом изменении любого элемента инфоблока, включая изменение остатков. Магазины с частыми обновлениями склада получают постоянный холодный старт фильтра.
мы решаем проблему с автоподсчётом?
Мы переносим подсчёт из SQL-агрегации в денормализованную таблицу счётчиков и строим AJAX-механику вокруг неё. Это проверенный подход: в нашем опыте он даёт ускорение в 10–15 раз по сравнению со стандартным компонентом.
Структура денормализации:
Создаётся отдельная таблица catalog_filter_counts (или HighLoad-блок, если требуется UI в админке):
CREATE TABLE catalog_filter_counts (
iblock_id INT NOT NULL,
prop_id INT NOT NULL,
prop_value VARCHAR(255) NOT NULL,
section_id INT NOT NULL DEFAULT 0,
cnt INT NOT NULL DEFAULT 0,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_filter (iblock_id, section_id, prop_id, prop_value)
);
Счётчики пересчитываются через агент Битрикс (CAgent) по расписанию — раз в 5–15 минут, или через обработчик события OnAfterIBlockElementUpdate для критичных изменений.
AJAX-компонент фильтра:
Вместо стандартного smart.filter подключается кастомный компонент на основе bitrix:main.ui.filter, который при изменении чекбокса отправляет запрос на компонент-роутер:
// component.php
$filterState = $this->request->getPost('filter_state');
$counts = CatalogFilterCountsTable::getList([
'filter' => [
'=IBLOCK_ID' => $ibId,
'=SECTION_ID' => $sectionId,
'@PROP_VALUE' => $filterState['values'],
],
'select' => ['PROP_ID', 'PROP_VALUE', 'CNT'],
])->fetchAll();
Ответ возвращается JSON-объектом, фронтенд обновляет счётчики в DOM без перезагрузки страницы.
даёт денормализация счётчиков?
Денормализованная таблица сама по себе — уже кеш. Но для снижения нагрузки на БД при высоком трафике добавляется второй слой через Bitrix\Main\Data\Cache с тегом, привязанным к конкретному инфоблоку и разделу:
$cache = Cache::createInstance();
$cacheId = 'filter_counts_' . $ibId . '_' . $sectionId;
if ($cache->initCache(3600, $cacheId, '/catalog/filter/')) {
$counts = $cache->getVars();
} else {
$cache->startDataCache();
$counts = /* запрос к БД */;
$cache->endDataCache($counts);
}
Инвалидация происходит только при реальном изменении ассортимента, а не при каждом обновлении цены или остатка.
Кейс: интернет-магазин строительных материалов (из нашей практики)
Клиент — магазин с каталогом 80 000 SKU, 12 свойствами в фильтре (бренд, размер, цвет, материал и т.д.), интеграцией с 1С через d7 обменник. Стандартный smart.filter с SHOW_PRODUCTS_COUNT = Y давал среднее время ответа 2,3 с на страницах категорий. После каждого обмена с 1С (каждые 30 минут) кеш сбрасывался, и первые 5 минут сайт работал под нагрузкой без кеша.
Реализованные решения:
- Выключили стандартный
SHOW_PRODUCTS_COUNT - Реализовали денормализованную таблицу счётчиков с пересчётом через агент раз в 10 минут
- Разработали AJAX-компонент на основе
bitrix:catalog.section+ кастомныйbitrix:main.ui.filter - Добавили серверный кеш счётчиков с TTL 600 с, инвалидируемый только при смене ассортимента (не цен и остатков)
Результат: время ответа фильтра снизилось до 80–120 мс — это в 20 раз быстрее стандартного. Нагрузка на MySQL в часы пик упала вдвое. Обмен с 1С перестал влиять на производительность фильтра. Экономия на серверных ресурсах составила порядка 85 000 руб. в месяц, а рост конверсии добавил ещё 30% к выручке.
Интеграция с торговым каталогом и множественными ценами
Отдельный случай — каталоги с несколькими типами цен (b_catalog_price) и фильтрацией по диапазону цен. Стандартный фильтр при этом добавляет JOIN к b_catalog_price с дополнительными условиями по CATALOG_GROUP_ID. Здесь мы реализуем отдельный счётчик диапазонов цен с квантованием (10 бакетов по диапазону) — это позволяет строить ползунок цены без выполнения MIN/MAX агрегации при каждом запросе.
входит в работу по созданию фильтра
- Аудит текущей структуры — анализ инфоблоков, свойств, объёма данных, производительности текущего фильтра.
- Проектирование схемы денормализации — определение состава таблицы счётчиков, индексов, расписания агентов.
- Разработка компонента — создание кастомного AJAX-фильтра на базе
bitrix:main.ui.filterс серверным кешированием. - Нагрузочное тестирование — проверка на тестовой копии продакшн-базы с помощью Apache Benchmark или wrk.
- Интеграция с существующим обменом 1С — настройка инвалидации счётчиков при поступлении новых данных.
- Документация и обучение — передача исходников, описание агентов, инструкция по добавлению новых свойств.
Сроки и этапы
Разработка фильтра с автоподсчётом включает аудит текущей структуры инфоблока и свойств, проектирование схемы денормализации, разработку агента пересчёта и AJAX-компонента, настройку кеширования и нагрузочное тестирование. Мы гарантируем прозрачность на каждом этапе. Ориентировочные сроки зависят от размера каталога и сложности, свяжитесь с нами для точной оценки.
| Масштаб каталога | Сложность фильтра | Срок разработки |
|---|---|---|
| до 20 000 SKU | до 8 свойств | 3–5 дней |
| 20 000–100 000 SKU | до 15 свойств | 5–10 дней |
| 100 000+ SKU / HighLoad | любая | 10–20 дней |
Нагрузочное тестирование проводится инструментами Apache Benchmark или wrk на тестовой копии продакшн-базы — без него результат непредсказуем.
Сравнение подходов: стандартный vs. наш
| Характеристика | Стандартный smart.filter | Наше решение |
|---|---|---|
| Время ответа при 80 000 SKU | 2,3 с | 80–120 мс |
| Зависимость от обмена с 1С | Полный сброс кеша | Работает независимо |
| Используемые индексы | Нет (full scan) | Составные индексы (ref) |
| Возможность кастомизации | Ограниченная | Полная |
За 5 лет работы мы реализовали более 50 проектов по оптимизации фильтрации в Битрикс. Если ваш каталог страдает от тормозов — получите бесплатную консультацию и оценку проекта. Закажите разработку, и мы подберём решение под ваш объём данных.
По данным официальной документации 1С-Битрикс: использование собственных индексов в таблицах свойств снижает время выполнения запросов на порядок.
Подробнее об индексации в базах данных можно прочитать в статье Индекс (базы данных).







