Налаштування партиціонування таблиць для 1С-Bitrix
Таблиця b_stat_hit розрослася до 50 мільйонів рядків, DELETE старих записів блокує її на хвилини, а SELECT за діапазоном дат іде через full scan. Партиціонування розбиває одну таблицю на фізично окремі секції (partitions) — запити звертаються тільки до потрібної секції, видалення старих даних — миттєве DROP PARTITION замість важкого DELETE.
Які таблиці Bitrix варто партиціонувати
Не всі таблиці вигадовують від партиціонування. Кандидати — великі таблиці з часовим виміром:
| Таблиця | Вміст | Характер росту |
|---|---|---|
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)) (...);
Перевіріть, що Bitrix не використовує 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. Миттєва операція: файл секції фізично видаляється.
Обмеження в контексті Bitrix
-
Оновлення ядра. Модуль
mainпри оновленні може виконатиALTER TABLE— якщо структура таблиці змінилася, а партиції не враховані, оновлення може зламатися. Ведіть список партиціонованих таблиць та перевіряйте перед оновленням. -
ORM D7.
Bitrix\Main\ORMне знає про партиції — запити працюють прозоро, але оптимізатор MySQL виконає partition pruning тільки якщо в WHERE є умова за стовпцем партиціонування. - Обмеження InnoDB. Максимум 8192 партиції на таблицю (MySQL 8). Для щоденного партиціонування — це 22 роки.
Що налаштовуємо
- Аналіз таблиць-кандидатів: розмір, характер запитів, ріст
- Зміна первинних ключів для сумісності з партиціонуванням
- Створення RANGE-партицій за датою
- Cron-скрипт для автоматичної ротації партицій
- Перевірка сумісності з оновленнями ядра Bitrix
- Тестування: час виконання SELECT та DELETE до та після партиціонування







