База данных — узкое место номер один у большинства highload-проектов на Битрикс. Когда кэш уже выжат, всё упирается в MySQL: индексы, буферы InnoDB и тяжёлые выборки каталога. Разберём, что настраивать в конфиге, а что — в схеме и запросах.
Базовые настройки InnoDB
Битрикс работает на InnoDB, и его настройки в my.cnf определяют половину производительности. Ключевые параметры:
| Параметр | Рекомендация |
|---|---|
innodb_buffer_pool_size | 60–70% RAM выделенного под БД сервера |
innodb_log_file_size | 256–512 МБ для стабильной записи |
innodb_flush_log_at_trx_commit | 2 при допустимости потери 1 сек транзакций |
innodb_flush_method | O_DIRECT для обхода двойного кэширования |
tmp_table_size / max_heap_table_size | Равные, чтобы избежать временных таблиц на диске |
Главный из них — buffer pool. Если данные и индексы не помещаются в память, каждый промах уходит на диск, и никакие индексы не спасут. Проверяйте Innodb_buffer_pool_reads — рост означает нехватку памяти.
READ COMMITTED (transaction_isolation = READ-COMMITTED) и sql_mode без ONLY_FULL_GROUP_BY. Иначе будут ошибки в ядре.Ищем тяжёлые запросы
Оптимизацию всегда начинают с фактов, а не догадок. Включите лог медленных запросов:
slow_query_log = 1;long_query_time = 0.5(позже снижаем до 0.1);log_queries_not_using_indexes = 1на время анализа.
Собранный лог прогоняйте через pt-query-digest — он сгруппирует похожие запросы и покажет топ по суммарному времени. Это важнее, чем один самый медленный запрос: частая выборка каталога, повторяющаяся тысячи раз, съедает больше ресурсов, чем редкий отчёт.
Параллельно смотрите панель SQL Битрикс с SHOW_SQL_STAT — она укажет место в коде, откуда пришёл проблемный запрос.
Индексы и EXPLAIN
Найдя тяжёлый запрос, прогоните его через EXPLAIN и смотрите на признаки проблем:
type: ALL— полное сканирование таблицы, нужен индекс;Using filesort— сортировка без индекса;Using temporary— временная таблица, часто из-заGROUP BY;rows— сколько строк реально просматривается.
Индексы нужны прежде всего на пользовательских свойствах инфоблоков и полях, по которым идёт фильтрация и сортировка каталога. Битрикс позволяет создавать индексы на свойствах через настройки инфоблока, а также добавлять составные индексы вручную под конкретные выборки.
Инфоблоки 2.0 и facet-индекс
Для больших каталогов архитектура хранения свойств решает всё. В режиме 1.0 все свойства всех элементов лежат в одной таблице b_iblock_element_property — это гигантская таблица с медленными выборками по свойствам.
Инфоблоки 2.0 хранят свойства каждого инфоблока в отдельной таблице (b_iblock_element_prop_sXX), где каждое свойство — отдельная колонка. Выигрыш:
- выборки по свойствам ускоряются кратно — работает по индексам колонок;
- умный фильтр использует facet-индекс — предрассчитанную таблицу для мгновенной фильтрации;
- меньше блокировок при массовом обновлении цен и остатков.
Перевод инфоблока в 2.0 делается в его настройках; для крупных каталогов это одно из самых эффективных решений по нагрузке на БД.
Репликация и разделение чтения
Когда одна БД перестаёт справляться, применяют master-slave репликацию. Запись идёт в master, а тяжёлое чтение (каталог, поиск) распределяется по slave-репликам. Битрикс поддерживает это штатно через модуль cluster.
| Узел | Роль |
|---|---|
| Master | Все операции записи (заказы, обмен, админка) |
| Slave 1..N | Чтение каталога, поиска, отчётов |
Модуль сам направляет SELECT на реплики, а изменяющие запросы — на master, учитывая задержку репликации. Для операций, где важна консистентность сразу после записи, есть механизм принудительного чтения с master.
Регулярное обслуживание БД
База деградирует со временем, если её не обслуживать. Что делать регулярно:
- чистить служебные таблицы:
b_event_log,b_perf_*, статистику, старые сессии в БД; - следить за таблицей поисковой индексации и агентами, которые её наполняют;
- контролировать фрагментацию и при необходимости выполнять
OPTIMIZE TABLEв окно низкой нагрузки; - архивировать старые заказы и логи обмена, если они разрослись до миллионов строк.
Разросшиеся служебные таблицы — частая скрытая причина деградации: buffer pool забивается мусором, и полезные данные вытесняются на диск.
Итог
Оптимизация MySQL под Битрикс идёт слоями: сначала правильные настройки InnoDB и достаточный buffer pool, затем поиск тяжёлых запросов по slow log, индексы и EXPLAIN, перевод крупных каталогов на инфоблоки 2.0 с facet-индексом и только потом — репликация для масштабирования чтения. Плюс регулярная чистка служебных таблиц, чтобы база не деградировала.
Мы в B2Bsite настраиваем базу под нагрузку: тюним конфиг InnoDB, разбираем медленные запросы, переводим каталоги на 2.0 и строим репликацию с разделением чтения и записи. Если проект упирается в БД — поможем найти причину и вернуть отзывчивость под реальной нагрузкой.
Частые вопросы
Какой размер innodb_buffer_pool_size выставить?
Ориентир — 60–70% оперативной памяти сервера, выделенного под БД. Данные и индексы должны помещаться в буфер, иначе каждый промах уходит на диск. Рост Innodb_buffer_pool_reads сигнализирует о нехватке памяти.
Зачем Битрикс требует READ COMMITTED?
Ядро рассчитано на этот уровень изоляции транзакций. При других уровнях возможны блокировки и ошибки в работе модулей. Задаётся параметром transaction_isolation = READ-COMMITTED в конфиге MySQL.
Что даёт перевод инфоблока в режим 2.0?
Свойства хранятся в отдельной таблице инфоблока, каждое как колонка, что кратно ускоряет выборки по свойствам. Дополнительно становится доступен facet-индекс для мгновенной работы умного фильтра.
Как понять, что запросу не хватает индекса?
Прогоните его через EXPLAIN. Признаки — type: ALL (полное сканирование), Using filesort, Using temporary и большое число в колонке rows. Это указывает, где нужен индекс или переписывание запроса.
Репликация ускорит запись заказов?
Нет. Master-slave масштабирует только чтение — SELECT уходят на реплики. Запись по-прежнему идёт в один master. Если упирается запись, помогают шардинг, оптимизация обмена с 1С и очереди.
Нужно ли индексировать все поля каталога?
Нет. Каждый индекс замедляет вставку и обновление и занимает память в buffer pool. Индексируйте только поля, реально участвующие в WHERE, JOIN и ORDER BY тяжёлых запросов из slow log.
Почему база тормозит, хотя запросы вроде быстрые?
Частая причина — разросшиеся служебные таблицы: журнал событий, статистика, старые сессии. Они забивают buffer pool, вытесняя полезные данные на диск. Их нужно регулярно чистить и архивировать.
Поможем с настройкой и поддержкой Для разработчиков
Поможем с настройкой, доработкой и поддержкой Для разработчиков.