Прискорення Бітрікс: партиціювання таблиць MySQL
Партиціювання таблиць MySQL для 1С-Бітрікс — це техніка налаштування MySQL, яка вирішує проблему розростання таблиці b_stat_hit до 50 мільйонів рядків, коли DELETE старих записів блокує таблицю на хвилини, а SELECT по діапазону дат йде через повний скан. Це типова картина для проєктів без партиціювання. Наші інженери з 10+ річним досвідом, сертифікацією Бітрікс та понад 50 успішними проєктами гарантують коректне впровадження без простоїв. Партиціювання — розділення таблиці MySQL на фізичні секції. Запити звертаються лише до потрібної секції, видалення старих даних — миттєве DROP PARTITION замість важкого DELETE. В одному проєкті з 80 мільйонами хітів статистики час видалення даних за місяць скоротився з 12 хвилин до 0.1 секунди — це в 7200 разів швидше. На іншому проєкті з каталогом з 500 000 товарів і відвідуваністю 100 000 хостів на добу таблиця b_stat_hit росла на 3 мільйони рядків на день — після партиціювання проблема блокувань зникла.
Партиціювання не панацея, але для великих таблиць з часовим виміром воно дає приріст продуктивності в 10–50 разів на операціях вибірки та очищення. Ми використовуємо RANGE-партиціювання за датою — найпрозоріший і обслуговуваний варіант для Бітрікс. Нижче розберемо, які таблиці потрібно партиціювати в першу чергу і як це реалізувати без простоїв.
Які таблиці Бітрікс варто партиціювати?
Не всі таблиці виграють від партиціювання. Кандидати — великі таблиці з часовим виміром:
| Таблиця | Вміст | Характер росту | Рекомендація |
|---|---|---|---|
b_stat_hit |
Хіти статистики | Тисячі рядків/день | Партиціювати обов'язково |
b_stat_session |
Сесії відвідувачів | Тисячі рядків/день | Партиціювати |
b_event_log |
Лог подій | Сотні рядків/день | Партиціювати |
b_sale_order_history |
Історія змін замовлень | Десятки рядків/день | При обсязі > 1 млн |
b_search_content |
Пошуковий індекс | Зростає з каталогом | При обсязі > 5 млн |
b_iblock_element_property |
Властивості елементів інфоблоків | Зростає з каталогом | При обсязі > 10 млн |
Таблиці статистики — перший кандидат: дані старші 3 місяців рідко потрібні, а DELETE FROM b_stat_hit WHERE DATE_HIT < NOW() - INTERVAL 3 MONTH на 30 мільйонах рядків — це 10 хвилин блокування. Після партиціювання видалення займає мілісекунди.
Чому це важливо для продуктивності Бітрікс?
Без партиціювання MySQL сканує всю таблицю, навіть якщо потрібні дані за останній тиждень. З партиціями оптимізатор виконує partition pruning — відкидає секції, що не підходять під умову WHERE. Це знижує навантаження на I/O та CPU в десятки разів. Наприклад, SELECT з фільтром за датою на партиційованій таблиці виконується в 30–50 разів швидше. Для наочності — порівняння операцій:
| Операція | Об'єм даних | Час до партиціювання | Після партиціювання |
|---|---|---|---|
| DELETE старих хітів | 10 млн рядків | ~5 хвилин (блокування) | 0.001 секунди (DROP PARTITION) |
| SELECT по місяцю | 5 млн рядків | ~8 секунд (full scan) | ~0.2 секунди (partition pruning) |
Таке прискорення безпосередньо впливає на швидкість роботи звітів та очищення логів. Зв'яжіться з нами для аналізу вашої бази та оцінки ефекту.
Як автоматизувати ротацію партицій?
Після налаштування партицій потрібно забезпечити їх регулярне додавання та видалення. Використовуємо cron-скрипт на Bash, який викликається щомісяця. Приклад логіки:
#!/bin/bash MONTH=$(date +%Y-%m) PART_NAME="p_$MONTH" SQL="ALTER TABLE b_stat_hit REORGANIZE PARTITION p_future INTO (PARTITION $PART_NAME VALUES LESS THAN (TO_DAYS('$(date +%Y-%m-%d -d '+1 month'))'), PARTITION p_future VALUES LESS THAN MAXVALUE);" mysql -u user -p db -e "$SQL" # Видалення старої партиції, наприклад, старшої 6 місяців OLD_PART=$(date +%Y-%m -d '-6 months') OLD_SQL="ALTER TABLE b_stat_hit DROP PARTITION p_$OLD_PART;" mysql -u user -p db -e "$OLD_SQL" Скрипт повинен бути запущений з правами на зміну таблиць. Ми налаштовуємо його на сервері та тестуємо автоматичну ротацію.
Як реалізуємо партиціювання: покроково
- Аналізуємо таблиці-кандидати: розмір, характер запитів, швидкість росту.
- Змінюємо первинні ключі, якщо потрібно (додаємо стовпець дати).
- Створюємо RANGE-партиції за датою. Приклад для
b_stat_hit:
ALTER TABLE b_stat_hit PARTITION BY RANGE (TO_DAYS(DATE_HIT)) ( PARTITION p_jan VALUES LESS THAN (TO_DAYS('2099-02-01')), PARTITION p_feb VALUES LESS THAN (TO_DAYS('2099-03-01')), PARTITION p_mar VALUES LESS THAN (TO_DAYS('2099-04-01')), PARTITION p_future VALUES LESS THAN MAXVALUE ); Документація MySQL Partitioning вимагає, щоб стовпець партиціювання входив у кожен унікальний індекс та первинний ключ. Для b_stat_hit первинний ключ — ID. Приводимо його до складеного:
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 безпечний.
-
Налаштовуємо cron-скрипт для ротації партицій:
- Створення нової партиції:
REORGANIZE PARTITION p_future INTO (PARTITION p_apr VALUES LESS THAN (TO_DAYS('2099-05-01')), PARTITION p_future VALUES LESS THAN MAXVALUE). - Видалення старої:
ALTER TABLE b_stat_hit DROP PARTITION p_old.
Тестуємо продуктивність: заміряємо час SELECT та DELETE до і після. Зазвичай покращення в 10–50 разів, а видалення даних — в тисячі разів швидше.
Що входить у нашу роботу
- Аналіз бази даних та виявлення таблиць-кандидатів.
- Зміна первинних ключів без втрати даних.
- Створення RANGE-партицій за датою.
- Розробка та налаштування cron-скрипта для автоматичної ротації.
- Перевірка сумісності з оновленнями ядра Бітрікс.
- Документування всіх змін.
- Підтримка після впровадження (1 місяць).
Замовте консультацію інженера з партиціювання. Ми проаналізуємо вашу базу та запропонуємо оптимальне рішення.
Обмеження в контексті Бітрікс
- Оновлення ядра. Модуль
mainпри оновленні може виконати ALTER TABLE — якщо структура змінилася, а партиції не враховані, оновлення може зламатися. Ми ведемо список партиційованих таблиць і перевіряємо перед кожним оновленням. - ORM D7.
Bitrix\Main\ORMне знає про партиції — запити працюють прозоро, але оптимізатор MySQL виконає partition pruning тільки якщо в WHERE є умова по стовпцю партиціювання. - InnoDB обмеження. Максимум 8192 партиції на таблицю (MySQL 8). Для місячного партиціювання — це понад 680 років.
Партиціювання таблиць MySQL для 1С-Бітрікс — перевірений спосіб підвищення продуктивності, особливо на високонавантажених проєктах. Отримайте безкоштовну консультацію інженера з партиціювання. Замовте аналіз продуктивності вже сьогодні.
- Створення нової партиції:







