Ускорение работы Highload-блоков: подходы и инструменты
Представьте: highload-блок с историей заказов на 5 млн строк — запрос выборки по дате фильтрации выполняется 40 секунд. После оптимизации — 8 миллисекунд. Такое возможно при правильном индексировании, кешировании и партиционировании. Highload-блоки (модуль highloadblock) — механизм Битрикс для хранения произвольных данных в отдельных таблицах. Популярные применения: журналы событий, каталоги товаров с нестандартной структурой, пользовательские профили, накопительные данные (история заказов, аналитика, очереди). Пока строк меньше 50–100 тысяч — всё работает нормально. При 1–10 миллионах строк начинаются проблемы: ORM Битрикс генерирует неоптимальные запросы, индексы не покрывают реальные выборки, JOINы тормозят. Мы сталкивались с проектами, где время выборки достигало 40 секунд — после оптимизации падало до 8 миллисекунд. Экономия времени на каждом запросе — до 99.9%.
Почему highload-блоки тормозят на больших данных?
Основные антипаттерны при работе с Highload:
- Отсутствие нужных индексов. Highload-блок создаёт таблицу с первичным ключом
IDи автоинкрементом. Пользовательские поля типаUF_*не индексируются автоматически. ВыборкаgetList(['filter' => ['UF_PRODUCT_ID' => 123]])при миллионе строк — это table scan. - SELECT *-подобные запросы. ORM Битрикс по умолчанию выбирает все поля. Если у записи 30 UF-полей, включая TEXT и FILE, это дорогой запрос даже при малом result set.
- Неограниченные выборки без пагинации.
DataManager::getList()безlimitвернёт все записи в память PHP. - Связанные таблицы через Reference. Если Highload связан с другим Highload или инфоблоком через Reference-поля — ORM строит JOIN, который без правильных индексов убивает производительность.
- Частые UPDATE по полям без индекса. Типично для статусных полей, счётчиков.
Как диагностировать узкие места?
Включаем лог медленных запросов MySQL:
[mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 1 log_queries_not_using_indexes = 1 Как правильно индексировать highload-таблицы?
Добавляем индексы через прямой SQL — в агенте при установке или в migration-скрипте:
$connection = \Bitrix\Main\Application::getConnection(); $tableName = 'b_hl_product_catalog'; // Пример $connection->queryExecute( "CREATE INDEX IF NOT EXISTS idx_product_id ON {$tableName} (UF_PRODUCT_ID)" ); $connection->queryExecute( "CREATE INDEX IF NOT EXISTS idx_status_date ON {$tableName} (UF_STATUS, UF_DATE_CREATE)" ); Что делать, если ORM тормозит даже с индексами?
Явный SELECT нужных полей. Никогда не запрашиваем select: ['*'] или пустой массив select:
$result = ProductCatalogTable::getList([ 'select' => ['ID', 'UF_NAME', 'UF_PRICE', 'UF_ACTIVE'], 'filter' => ['UF_CATEGORY_ID' => $categoryId, 'UF_ACTIVE' => 1], 'order' => ['UF_SORT' => 'ASC'], 'limit' => 50, 'offset' => ($page - 1) * 50, ]); Прямые SQL-запросы для агрегации. Для COUNT, SUM, GROUP BY с большими таблицами — прямой SQL в 5–7 раз быстрее ORM. Используйте Bitrix\Main\Application::getConnection()->query().
Партиционирование для хронологических данных. Если Highload хранит логи или события с датой — партиционирование по диапазону дат резко ускоряет выборки за период:
ALTER TABLE b_hl_event_log PARTITION BY RANGE (YEAR(UF_DATE_CREATE) * 100 + MONTH(UF_DATE_CREATE)) ( PARTITION p_jan VALUES LESS THAN (202402), PARTITION p_feb VALUES LESS THAN (202403), PARTITION p_future VALUES LESS THAN MAXVALUE ); Кеширование результатов. Highload-данные хорошо кешируются через Bitrix\Main\Data\Cache с тегированием. Пример реализации:
class CachedProductCatalog { private const CACHE_TAG = 'hl_product_catalog'; private const CACHE_TTL = 3600; public function getByCategory(int $categoryId): array { $cache = \Bitrix\Main\Data\Cache::createInstance(); $cacheKey = 'hl_catalog_cat_' . $categoryId; if ($cache->initCache(self::CACHE_TTL, $cacheKey, '/hl/catalog/')) { return $cache->getVars(); } $cache->startDataCache(); // Fetch from DB $result = $this->fetchFromDb($categoryId); // Тегированный кеш $tagCache = new \Bitrix\Main\Data\TaggedCache(); $tagCache->startTagCache('/hl/catalog/'); $tagCache->registerTag(self::CACHE_TAG . '_' . $categoryId); $tagCache->endTagCache(); $cache->endDataCache($result); return $result; } } Бенчмарки: что даёт каждая оптимизация
| Оптимизация | Таблица 1М строк | Таблица 10М строк |
|---|---|---|
| Добавление индекса по фильтруемому полю | 4000 ms → 5 ms | 40000 ms → 8 ms |
| SELECT только нужных полей | 800 ms → 120 ms | — |
| Кеш результата (попадание) | 120 ms → 0.5 ms | — |
| Прямой SQL вместо ORM (агрегация) | 350 ms → 45 ms | 3000 ms → 80 ms |
| Партиционирование по дате | — | 3000 ms → 60 ms |
Пошаговый план оптимизации
- Аудит Highload-блоков. Сбор структуры, объёмов данных, типичных запросов. Включение slow query log.
- Анализ узких мест. Выявление топ-5 тормозящих запросов по времени.
- Добавление индексов. Создание одиночных и составных индексов под реальные фильтры.
- Рефакторинг кода. Замена
select: ['*']на явный список, внедрение лимитов и пагинации. - Кеширование. Внедрение тегированного кеша для часто запрашиваемых данных.
- Партиционирование. Для хронологических таблиц — разбиение по дате.
- Нагрузочное тестирование. AB-сравнение производительности до и после.
Что входит в работу
- Аудит Highload-блоков: структура, объём данных, типичные запросы и slow query log.
- Анализ узких мест: выявление топ-5 тормозящих запросов.
- Добавление индексов: одиночных и составных под реальные паттерны фильтрации.
- Рефакторинг кода: явный select, лимиты, пагинация, замена ORM на прямой SQL там, где это даёт существенный выигрыш.
- Внедрение тегированного кеша для тяжёлых выборок.
- Партиционирование хронологических таблиц (при необходимости).
- Нагрузочное тестирование с AB-сравнением до/после.
- Документация и обучение вашего разработчика.
Сроки и стоимость
Сроки работ: аудит + индексы + кеш — 2–3 недели. Полная оптимизация с партиционированием и рефакторингом — 4–8 недель. Стоимость рассчитывается индивидуально в зависимости от объёма данных и сложности. Наша команда с многолетним опытом в Битрикс, реализовавшая более 50 проектов по оптимизации, гарантирует прозрачный подход и измеримые результаты. Свяжитесь с нами для предварительной оценки — мы предложим план работ с контрольными точками. Закажите аудит производительности и получите консультацию инженера.
Подробнее о Highload-блоках в официальной документации.







