Партиции MySQL для b_iblock_element и корзины в Битриксе
Зачем вообще партиции у b_iblock_element
Таблица b_iblock_element общая для всех инфоблоков. Если в базе много разных IBLOCK_ID, но горячие запросы всегда фильтруют конкретный инфоблок (каталог, новости, служебный справочник), MySQL может подрезать партиции по ключу разбиения и не сканировать лишние секции. Эффект заметен при большом объёме строк и регулярных выборках вида WHERE IBLOCK_ID = ….
Составной первичный ключ и RANGE по IBLOCK_ID
Классический первичный ключ там один столбец — ID. Чтобы разбить по IBLOCK_ID, в примерах часто делают составной ключ и партиционируют по диапазонам идентификаторов инфоблоков:
ALTER TABLE `b_iblock_element`
DROP PRIMARY KEY,
ADD CONSTRAINT `id_iblock_id` PRIMARY KEY (`ID`, `IBLOCK_ID`)
PARTITION BY RANGE COLUMNS(`IBLOCK_ID`) (
PARTITION `p0` VALUES LESS THAN (45),
PARTITION `p1` VALUES LESS THAN (46),
PARTITION `p2` VALUES LESS THAN (52),
PARTITION `p3` VALUES LESS THAN MAXVALUE
);Границы 45, 46, 52 взяты как иллюстрация — подставьте реальные значения из своей схемы после просмотра занятости по IBLOCK_ID.
Сразу после изменения проверьте, что оптимизатор действительно режет партиции:
EXPLAIN PARTITIONS SELECT * FROM b_iblock_element WHERE IBLOCK_ID = 45;Что нужно помнить перед ALTER
- Операция трогает всю таблицу: планируйте окно или прогон на копии.
- Составной первичный ключ меняет модель уникальности: убедитесь, что приложение и все внешние ссылки на элементы согласованы (в ядре связи обычно по
IBLOCK_ID+ID, но сторонние отчёты и интеграции стоит проверить). - После смены первичного ключа пересмотрите индексы и дампы: логика восстановления должна остаться предсказуемой.
- Партиционирование не заменяет нормальные индексы по тем полям, по которым вы реально фильтруете.
Разнести строки корзины: KEY по FUSER_ID
Для очень крупной b_sale_basket иногда предлагают разнести строки по нескольким секциям через PARTITION BY KEY(FUSER_ID), сохраняя уникальность пары строки пользователя через составной первичный ключ:
ALTER TABLE `b_sale_basket`
DROP PRIMARY KEY,
ADD CONSTRAINT `idx_user_id` PRIMARY KEY (`ID`, `FUSER_ID`)
PARTITION BY KEY (`FUSER_ID`) PARTITIONS 10;На больших объёмах такой DDL может выполняться заметное время — оцените на staging и следите за нагрузкой на диск. Любое изменение ключа таблицы, с которой тесно работает модуль Sale, требует регрессии по оформлению заказа и фоновым агентам.
Итог
Партиции — инструмент для узкого класса узких мест: когда основной фильтр совпадает с ключом разбиения и вы готовы платить цену сопровождения DDL. Для типичного Битрикса чаще выигрывают индексы, кэш и прозрачная схема инфоблоков; разбиение таблиц ядра оставляйте осознанным шагом после замеров, а не «на всякий случай».
Не хотите копаться сами?
Починю за 1-3 дня. Без предоплаты — оплата по результату.
15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии