Настройка партиционирования таблиц для 1С-Битрикс
Таблица b_stat_hit разрослась до 50 миллионов строк, DELETE старых записей блокирует её на минуты, а SELECT по диапазону дат идёт через full scan. Партиционирование разбивает одну таблицу на физически отдельные секции (partitions) — запросы обращаются только к нужной секции, удаление старых данных — мгновенное DROP PARTITION вместо тяжёлого DELETE.
Какие таблицы Битрикс стоит партиционировать
Не все таблицы выигрывают от партиционирования. Кандидаты — большие таблицы с временны́м измерением:
| Таблица | Содержимое | Характер роста |
|---|---|---|
b_stat_hit |
Хиты статистики | Тысячи строк/день |
b_stat_session |
Сессии посетителей | Тысячи строк/день |
b_event_log |
Лог событий | Сотни строк/день |
b_sale_order_history |
История изменений заказов | Десятки строк/день |
b_search_content |
Поисковой индекс | Растёт с каталогом |
b_iblock_element_property |
Свойства элементов инфоблоков | Растёт с каталогом |
Таблицы статистики — первый кандидат: данные старше 3 месяцев редко нужны, а DELETE FROM b_stat_hit WHERE DATE_HIT < '2025-01-01' на 30 миллионах строк — это 10 минут блокировки.
Реализация: RANGE-партиционирование по дате
Пример для b_stat_hit:
ALTER TABLE b_stat_hit
PARTITION BY RANGE (TO_DAYS(DATE_HIT)) (
PARTITION p_2025_01 VALUES LESS THAN (TO_DAYS('2025-02-01')),
PARTITION p_2025_02 VALUES LESS THAN (TO_DAYS('2025-03-01')),
PARTITION p_2025_03 VALUES LESS THAN (TO_DAYS('2025-04-01')),
PARTITION p_future VALUES LESS THAN MAXVALUE
);
Важно: MySQL требует, чтобы столбец партиционирования входил в каждый уникальный индекс и первичный ключ таблицы. Для b_stat_hit первичный ключ — ID. Нужно либо изменить PK на (ID, DATE_HIT), либо использовать PARTITION BY RANGE(ID) — но тогда теряется привязка к датам.
Практическое решение: удалить автоинкрементный PK, создать составной:
ALTER TABLE b_stat_hit DROP PRIMARY KEY, ADD PRIMARY KEY (ID, DATE_HIT);
ALTER TABLE b_stat_hit PARTITION BY RANGE (TO_DAYS(DATE_HIT)) (...);
Проверьте, что Битрикс не использует ID для JOIN — если использует, составной PK безопасен (ID остаётся уникальным внутри каждой партиции, а автоинкремент продолжает работать).
Обслуживание партиций
Ежемесячный cron-скрипт для ротации:
-
Создание новой партиции —
ALTER TABLE b_stat_hit REORGANIZE PARTITION p_future INTO (PARTITION p_2025_04 VALUES LESS THAN (TO_DAYS('2025-05-01')), PARTITION p_future VALUES LESS THAN MAXVALUE). -
Удаление старых —
ALTER TABLE b_stat_hit DROP PARTITION p_2024_10. Мгновенная операция: физически удаляется файл секции.
Ограничения в контексте Битрикс
-
Обновления ядра. Модуль
mainпри обновлении может выполнитьALTER TABLE— если структура таблицы изменилась, а партиции не учтены, обновление может сломаться. Ведите список партиционированных таблиц и проверяйте перед обновлением. -
ORM D7.
Bitrix\Main\ORMне знает о партициях — запросы работают прозрачно, но оптимизатор MySQL выполнит partition pruning только если в WHERE есть условие по столбцу партиционирования. - InnoDB ограничения. Максимум 8192 партиции на таблицу (MySQL 8). Для ежедневного партиционирования — это 22 года.
Что настраиваем
- Анализ таблиц-кандидатов: размер, характер запросов, рост
- Изменение первичных ключей для совместимости с партиционированием
- Создание RANGE-партиций по дате
- Cron-скрипт для автоматической ротации партиций
- Проверка совместимости с обновлениями ядра Битрикс
- Тестирование: время выполнения SELECT и DELETE до и после партиционирования







