Страница каталога с 30 тысячами товаров генерирует 150 SQL-запросов, а сервер MySQL упирается в 90% CPU — это не проблема кода, это отсутствие профилирования. Без slow_query_log вы гадаете, какой запрос съедает ресурсы — профилирование даёт чёткий ответ. За десять лет мы провели более 50 аудитов MySQL на проектах 1С-Битрикс: каждый второй проект имел схожие паттерны — N+1 запросы, отсутствие индексов на ключевых таблицах (b_iblock_element, b_catalog_price), неоптимальные буферы InnoDB. Результат — страницы грузятся 5–7 секунд, сервер падает при пиковых нагрузках. Для диагностики мы используем slow query log, pt-query-digest и EXPLAIN ANALYZE, а также встроенный трекер Битрикс для ORM-запросов. Средняя экономия времени загрузки после оптимизации — 50–70%. Профилирование MySQL-запросов Битрикс позволяет снизить нагрузку CPU в 3-5 раз, а TTFB — на 60-80%. Типичная экономия на серверной инфраструктуре — до 300 000 руб./год.
Пошаговая инструкция: включение slow_query_log
- На сервере MySQL выполните
SET GLOBAL slow_query_log = 'ON'; - Установите порог:
SET GLOBAL long_query_time = 0.5; - Укажите файл лога:
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log'; - Включите логирование запросов без индексов:
SET GLOBAL log_queries_not_using_indexes = 1; - Для постоянной конфигурации пропишите параметры в
/etc/mysql/conf.d/slow.cnf.
Как выполняется профилирование MySQL-запросов в 1С-Битрикс?
Основа — slow query log MySQL. Включаем его на 1–2 дня с порогом 0.5 секунды. Для production используем файл конфигурации с параметром min_examined_row_limit = 100, чтобы отсечь быстрые запросы по первичному ключу.
Анализ через pt-query-digest
Percona Toolkit — индустриальный стандарт. Утилита группирует запросы по шаблону, показывает частоту и общее время.
pt-query-digest /var/log/mysql/slow.log --limit 20 --report-format query_report > /tmp/slow_report.txt На Битрикс-проектах топ-5 проблемных запросов обычно содержит:
- N+1 при выборке свойств (
b_iblock_element_prop_s*) - Поштучная выборка цен (
b_catalog_price) - COUNT без индекса
- Полнотекстовый поиск по большой таблице
- Конкуренция за обновление сессий (
b_user_session)
EXPLAIN и EXPLAIN ANALYZE
Для каждого медленного запроса запускаем EXPLAIN. Критические признаки: type = ALL (full scan), rows > 1000, Extra: Using filesort / temporary.
EXPLAIN SELECT be.ID, be.NAME, bp.VALUE FROM b_iblock_element be LEFT JOIN b_iblock_element_prop_s5 bp ON bp.IBLOCK_ELEMENT_ID = be.ID WHERE be.IBLOCK_ID = 12 AND be.ACTIVE = 'Y' AND be.WF_STATUS_ID = 1 ORDER BY be.SORT ASC LIMIT 48 OFFSET 0; -- EXPLAIN ANALYZE (MySQL 8.0+) показывает реальное время EXPLAIN ANALYZE SELECT ... ; EXPLAIN ANALYZE работает втрое быстрее ручного анализа плана — сразу выдаёт узкие места.
Какие индексы критичны для Битрикс?
Несколько индексов, которые часто отсутствуют в стандартной установке:
CREATE INDEX idx_iblock_element_active_sort ON b_iblock_element (IBLOCK_ID, ACTIVE, WF_STATUS_ID, SORT); CREATE INDEX idx_catalog_price_product_group ON b_catalog_price (PRODUCT_ID, CATALOG_GROUP_ID); CREATE INDEX idx_user_session_timestamp ON b_user_session (TIMESTAMP_X); После создания индекса перезапускаем EXPLAIN — тип должен смениться с ALL на ref.
Почему N+1 — частая проблема в ORM Битрикс?
D7 ORM часто генерирует N+1 запросов. Диагностика через встроенный трекер:
\Bitrix\Main\Application::getConnection()->setTracker(new \Bitrix\Main\DB\SqlTracker(50)); // В конце запроса $tracker = \Bitrix\Main\Application::getConnection()->getTracker(); foreach ($tracker->getQueries() as $query) { if ($query->getTime() > 0.1) error_log($query->getSql() . ' [' . $query->getTime() . 's]'); } // Исправление: вместо поштучных запросов — batch выборка $ids = array_column($elements->fetchAll(), 'ID'); $prices = PriceTable::getList(['filter' => ['PRODUCT_ID' => $ids]])->fetchAll(); $priceMap = array_column($prices, null, 'PRODUCT_ID'); Пример отчета pt-query-digest
# Query 1: 12.5k calls, avg 0.8s, 97% of total time SELECT ... FROM b_iblock_element_prop_s8 ... # Query 2: 500 calls, avg 2.1s SELECT ... FROM b_catalog_price ... Кейс: оптовый дистрибьютор
Из нашей практики: сайт на Битрикс «Малый бизнес», каталог 28 000 позиций, 3 000 посетителей/день. Сервер 4 CPU, 8 GB RAM. Нагрузка на MySQL — 85–90% CPU. pt-query-digest показал, что 92% времени уходит на b_iblock_element_prop_s8 (таблица строковых свойств) — full scan на 280 000 строк. Один индекс idx_prop_s8_element_id снизил нагрузку до 15–20% CPU без каких-либо изменений в коде. TTFB упал с 5 с до 1,2 с. В среднем по нашим проектам экономия времени загрузки составляет 50–70%. Снижение CPU с 85% до 15% сэкономило 200 000 руб./год на серверах.
Инструменты мониторинга
| Инструмент | Тип | Преимущество |
|---|---|---|
| Percona Monitoring and Management | Полный стек | Графики QPS, latency, топ запросов в реальном времени |
| MySQL Workbench Performance Schema | GUI | Удобен для разовой диагностики |
| Grafana + mysql_exporter | Интеграция | Встраивается в существующий мониторинг |
Подробнее о slow query log: Wikipedia. Также рекомендуем официальную документацию D7 ORM для избежания N+1.
Что входит в работу
- Диагностика: включение slow log, сбор данных, отчёт с топ-20 медленных запросов.
- Оптимизация: создание индексов, рефакторинг N+1, настройка буферов MySQL.
- Мониторинг: установка PMM или Grafana, настройка алертов.
- Документация и обучение: описание всех изменений, рекомендации для разработчиков.
Если вы обнаружили медленные запросы — закажите аудит профилирования MySQL. Гарантируем — после нашей оптимизации нагрузка на базу снизится в 3–5 раз, а TTFB — на 60–80%. Свяжитесь с нами для бесплатной оценки вашего проекта.
Сроки
| Масштаб | Состав | Срок |
|---|---|---|
| Аудит | Включение slow log, анализ, отчёт | 1–2 дня |
| Оптимизация | Индексы, рефакторинг N+1, настройка буферов | 3–7 дней |
| Мониторинг | PMM или Grafana + алерты | 2–3 дня |
Закажите профилирование MySQL-запросов 1С-Битрикс — получите развернутый отчёт и рекомендации в течение дня.







