Пока в каталоге пара тысяч товаров, всё летает. Но на десятках и сотнях тысяч позиций, под оптовой нагрузкой и активным обменом с 1С, сайт вдруг начинает «тормозить без причины»: каталог грузится секундами, фильтр думает, сервер под пиковой загрузкой. В подавляющем большинстве случаев причина одна — база данных и неоптимизированные запросы.
Эта статья — практический разбор, как оптимизировать SQL-запросы и индексы в 1С-Битрикс: как найти медленные запросы через slow log и EXPLAIN, где нужны индексы, что делать со свойствами инфоблоков и умным фильтром, как писать эффективные выборки на D7 и подкреплять всё кэшем. Если сайт уже ощутимо тормозит, начните с аудита и оптимизации решения на 1С-Битрикс.
Коротко
- На больших каталогах узкое место — база: тяжёлые запросы и выборки по неиндексированным полям.
- Диагностика начинается со slow query log и EXPLAIN — не гадайте, измеряйте реальные запросы.
- Индексируйте под реальные запросы, переводите свойства инфоблоков в отдельные таблицы, включайте фасетный индекс.
- Пишите точные выборки на D7 (select/filter/limit) и подкрепляйте оптимизацию кэшем — они дополняют друг друга.
Почему база становится узким местом
Каждая страница каталога, каждое срабатывание умного фильтра и поиска превращаются в SQL-запросы к базе. Пока данных мало, даже неоптимальный запрос отрабатывает быстро — база успевает перебрать небольшие таблицы. Но с ростом каталога стоимость плохого запроса растёт нелинейно: перебор миллионов строк вместо доступа по индексу превращает миллисекунды в секунды.
Добавьте оптовую нагрузку (много одновременных пользователей) и активный обмен с 1С (постоянные вставки и обновления), и база становится главным узким местом. При этом код и кэш могут быть в порядке — упор именно в СУБД. Поэтому на крупных проектах оптимизация начинается не с «переписать компонент», а с анализа того, что и как спрашивают у базы.
Диагностика: slow query log
Оптимизация вслепую — пустая трата времени. Первый шаг всегда один: включить журнал медленных запросов (slow query log) и получить факты. В него попадают запросы, выполняющиеся дольше заданного порога, — это и есть ваши реальные проблемные места, а не догадки.
- Включите slow log. Задайте разумный порог (например, доли секунды) и включите журнал в настройках MySQL/MariaDB.
- Соберите данные под нагрузкой. Дайте журналу поработать в реальном или тестовом трафике, чтобы поймать типовые запросы.
- Сгруппируйте запросы. Найдите самые частые и самые тяжёлые — начинать нужно с них, а не со случайных.
- Зафиксируйте базовые метрики. Время выполнения и частота — чтобы потом измерить эффект оптимизации.
Именно slow log превращает субъективное «сайт тормозит» в конкретный список запросов, которые дают наибольший вклад в медленность. С него начинается любая осмысленная оптимизация базы.
Разбор запроса через EXPLAIN
Найдя тяжёлый запрос, его анализируют через EXPLAIN — команду, показывающую план выполнения. Она отвечает на главные вопросы: используются ли индексы, сколько строк перебирается, в каком порядке читаются таблицы.
| Поле EXPLAIN | Что означает | Сигнал проблемы |
|---|---|---|
| type | Тип доступа к таблице | ALL — полное сканирование |
| key | Используемый индекс | NULL — индекс не задействован |
| rows | Оценка перебираемых строк | Большое число |
| Extra | Доп. операции | Using filesort, Using temporary |
Цель оптимизации — заменить полное сканирование таблицы (type=ALL) доступом по индексу и сократить число перебираемых строк. Если EXPLAIN показывает ALL и большой rows на поле, по которому идёт фильтрация, — это прямой кандидат на индекс. Так «медленно» превращается в понятную, устранимую причину.
Индексы: когда помогают, когда вредят
Индекс — структура, позволяющая базе находить строки без перебора всей таблицы. Он резко ускоряет чтение, но у него есть цена: замедление вставки и обновления (индекс надо поддерживать) и дополнительное место на диске. Поэтому индексы добавляют осознанно, под конкретные запросы, а не на все поля «про запас».
- Индексируйте поля фильтрации. Те, по которым часто идёт WHERE, — активность, раздел, свойства фильтра.
- Индексируйте поля сортировки и соединений. ORDER BY и JOIN по неиндексированным полям порождают filesort и полные сканы.
- Учитывайте составные индексы. Для запросов по нескольким полям сразу порядок полей в индексе важен.
- Убирайте лишнее. Неиспользуемые индексы тормозят обмен с 1С (массовые вставки) и раздувают базу.
Ключевой принцип: индексы должны идти от реальных запросов из slow log, а не от интуиции. Избыточная индексация вредит записи так же, как недостаточная — чтению.
Свойства инфоблоков и хранение
Отдельная и очень частая проблема больших каталогов — хранение свойств инфоблоков. По умолчанию значения всех свойств лежат в общей таблице значений, и выборка по ним на большом каталоге медленная: база перебирает огромную таблицу «свойство — значение».
Решение штатное: для крупных инфоблоков включают режим хранения свойств в отдельной таблице (конвертация в настройках инфоблока). Тогда каждое свойство становится колонкой в нормальной таблице, которую можно индексировать, а выборки и фильтрация по свойствам ускоряются в разы. Это одна из первых оптимизаций, которую делают на крупных каталогах, и она часто даёт самый заметный эффект. Как эффективно обращаться к данным через современный API — в статье про D7 и ORM.
Умный фильтр и фасетный индекс
Умный фильтр (catalog.smart.filter) — один из самых нагруженных элементов каталога: на каждый набор условий он должен посчитать доступные значения и количество товаров. Без оптимизации это тяжёлые запросы по свойствам.
В 1С-Битрикс для этого есть фасетный индекс — специальная структура, которая заранее хранит агрегированные данные для фильтрации. С включённым фасетным индексом умный фильтр работает по подготовленным данным, а не пересчитывает всё на лету, и отвечает быстро даже на большом каталоге. Обязательное условие — свойства инфоблока в отдельной таблице (см. предыдущий раздел). Связка «отдельное хранение свойств + фасетный индекс» — база быстрого фильтра.
Оптимизация выборок на D7
Много медленности рождается не в самой базе, а в коде, который её неэффективно спрашивает. Классика антипаттерна — выбрать «всё обо всём» и отфильтровать в PHP, дёргать базу в цикле, тянуть лишние поля. API D7 (ORM) помогает писать точные запросы.
- select только нужного. Выбирайте конкретные поля, а не всю сущность целиком.
- filter на стороне базы. Фильтруйте в запросе, а не перебором в PHP.
- limit и постраничность. Не тяните тысячи записей, если нужны десятки.
- Избегайте запросов в цикле. Соберите данные одним запросом с соединением вместо N обращений.
- Кэшируйте выборки. D7 упрощает кэширование результатов часто повторяющихся запросов.
Грамотный запрос переносит работу на базу, где она делается эффективнее, и уменьшает объём передаваемых в PHP данных. Часто переписывание одной тяжёлой выборки на чистый D7 даёт больший эффект, чем любые настройки сервера.
Кэширование как второй слой
Оптимизация запросов и кэширование — не альтернативы, а два слоя одной стратегии. Самый быстрый запрос — тот, который не выполняется, потому что результат уже в кэше. Но и кэш не отменяет оптимизации: при «промахе» кэша или сбросе тегов запрос всё равно уйдёт в базу, и он должен быть быстрым.
В 1С-Битрикс работают несколько уровней: кэш компонентов, управляемый кэш с тегированной инвалидацией (обновляется точечно при изменении данных), композитный сайт для мгновенной отдачи статической части страниц. Правильная схема: оптимизированные запросы снижают стоимость промахов и пиковую нагрузку, а кэш убирает повторные обращения к базе на частых страницах. Вместе они дают устойчивую скорость под нагрузкой. Про то, как выкатывать такие изменения безопасно, — статья про CI/CD и деплой на 1С-Битрикс.
Настройки СУБД и сервера
Оптимизация запросов раскрывается полностью только на правильно настроенном окружении. Даже идеальные индексы упрутся в нехватку памяти под кэш базы или слабую конфигурацию сервера.
- Память под буферы. Достаточный буферный пул позволяет держать горячие данные и индексы в памяти.
- Актуальные версии. Свежие MySQL/MariaDB и PHP работают быстрее и эффективнее.
- Разделение нагрузки. На крупных проектах — вынос базы на отдельный сервер, реплики для чтения.
- Мониторинг. Наблюдение за загрузкой базы, медленными запросами и памятью в динамике.
Настройка СУБД и сервера — фундамент, на котором работает всё остальное. Подробно роль окружения мы разбирали в материале про хостинг и инфраструктуру на BitrixVM.
Измерение результата
Оптимизация без измерений — это вера, а не инженерия. Каждое изменение нужно оценивать по метрикам «до» и «после», иначе легко потратить время на то, что не влияет на скорость.
- Время ответа ключевых страниц. Каталог, карточка, фильтр, поиск — до и после.
- Slow log. Уменьшилось ли число и время медленных запросов.
- Нагрузка базы и сервера. Как ведёт себя система под пиком после изменений.
- Core Web Vitals. Итоговое влияние на реальный пользовательский опыт.
Работайте итеративно: замерили, нашли узкое место, исправили, снова замерили. И тестируйте изменения на копии данных перед выкладкой — нагрузочное тестирование покажет эффект без риска для боевого сайта.
Частые ошибки
- Оптимизация вслепую. Без slow log и EXPLAIN «улучшают» то, что не влияет на скорость.
- Индексы на всё подряд. Избыточная индексация тормозит обмен с 1С и раздувает базу.
- Свойства в общей таблице. Большой каталог с общим хранением свойств обречён на медленный фильтр.
- Фасетный индекс не включён. Умный фильтр пересчитывает всё на лету и тормозит.
- Запросы в цикле. N обращений к базе вместо одного соединения.
- Ставка только на кэш. Промах кэша обнажает неоптимизированный тяжёлый запрос.
- Нет измерений. Эффект оптимизации не проверяется метриками.
Чек-лист оптимизации
- Slow log включён. Собраны реальные медленные запросы под нагрузкой.
- Запросы разобраны. Через EXPLAIN найдены полные сканы и отсутствующие индексы.
- Индексы под запросы. Добавлены нужные, убраны лишние индексы.
- Свойства вынесены. Крупные инфоблоки переведены на отдельное хранение свойств.
- Фасетный индекс построен. Умный фильтр работает по подготовленным данным.
- Выборки на D7. Точные select/filter/limit, нет запросов в цикле.
- Кэш настроен. Компоненты, тегированный кэш, композит на частых страницах.
- Результат измерен. Метрики до/после, нагрузочный тест на копии данных.
Вывод
На больших каталогах и под оптовой нагрузкой скорость 1С-Битрикс решается на уровне базы данных. Оптимизация начинается не с догадок, а с фактов: slow query log и EXPLAIN показывают, что именно тормозит. Дальше — точечные индексы под реальные запросы, перевод свойств инфоблоков в отдельное хранение, фасетный индекс для умного фильтра и эффективные выборки на D7.
Подкрепите это кэшированием и правильной настройкой СУБД — и каталог останется быстрым даже под пиком. Главное — работать измеримо: замер, гипотеза, исправление, повторный замер. Такой подход превращает «сайт тормозит» в управляемую и решаемую инженерную задачу, а быструю базу — в устойчивое конкурентное преимущество вашего магазина.