Ускорение Highload-блоков: аудит, индексы, кеш, партиционирование

Ускорение работы Highload-блоков: подходы и инструменты Представьте: highload-блок с историей заказов на 5 млн строк — запрос выборки по дате фильтрации выполняется **40 секунд**. После оптимизации — **8 миллисекунд**. Такое возможно при правильном индексировании, кешировании и партиционировании.
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Ускорение Highload-блоков: аудит, индексы, кеш, партиционирование
Средний
~1-2 недели

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

Часто задаваемые вопросы

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

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1460
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1019
  • Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    764
  • Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    882
  • Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    809
  • Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1164

Ускорение работы 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

Пошаговый план оптимизации

  1. Аудит Highload-блоков. Сбор структуры, объёмов данных, типичных запросов. Включение slow query log.
  2. Анализ узких мест. Выявление топ-5 тормозящих запросов по времени.
  3. Добавление индексов. Создание одиночных и составных индексов под реальные фильтры.
  4. Рефакторинг кода. Замена select: ['*'] на явный список, внедрение лимитов и пагинации.
  5. Кеширование. Внедрение тегированного кеша для часто запрашиваемых данных.
  6. Партиционирование. Для хронологических таблиц — разбиение по дате.
  7. Нагрузочное тестирование. AB-сравнение производительности до и после.

Что входит в работу

  • Аудит Highload-блоков: структура, объём данных, типичные запросы и slow query log.
  • Анализ узких мест: выявление топ-5 тормозящих запросов.
  • Добавление индексов: одиночных и составных под реальные паттерны фильтрации.
  • Рефакторинг кода: явный select, лимиты, пагинация, замена ORM на прямой SQL там, где это даёт существенный выигрыш.
  • Внедрение тегированного кеша для тяжёлых выборок.
  • Партиционирование хронологических таблиц (при необходимости).
  • Нагрузочное тестирование с AB-сравнением до/после.
  • Документация и обучение вашего разработчика.

Сроки и стоимость

Сроки работ: аудит + индексы + кеш — 2–3 недели. Полная оптимизация с партиционированием и рефакторингом — 4–8 недель. Стоимость рассчитывается индивидуально в зависимости от объёма данных и сложности. Наша команда с многолетним опытом в Битрикс, реализовавшая более 50 проектов по оптимизации, гарантирует прозрачный подход и измеримые результаты. Свяжитесь с нами для предварительной оценки — мы предложим план работ с контрольными точками. Закажите аудит производительности и получите консультацию инженера.

Подробнее о Highload-блоках в официальной документации.