Индекс базы данных - это структура вроде алфавитного указателя в книге: вместо перелистывания всех страниц СУБД сразу открывает нужную. Запрос по полю без индекса заставляет MySQL просмотреть таблицу целиком - на таблице в миллион строк это секунды вместо миллисекунд, и именно так рождаются «сайт думает» и падения под нагрузкой. Найти проблемные места помогают журнал медленных запросов (slow query log) и команда EXPLAIN, а лечение часто укладывается в одну строку - добавление индекса.

Аналогия для нетехнических людей. Найти абонента по фамилии в бумажном телефонном справочнике легко - он отсортирован по фамилиям, это и есть индекс. А теперь найдите в том же справочнике всех с номером, заканчивающимся на 42: придётся читать каждую страницу. Ровно это делает база при запросе по полю без индекса.

Почему выборка без индекса ползает: что происходит внутри

Когда индекс есть, СУБД спускается по дереву индекса за несколько шагов и достаёт нужные строки - десятки операций. Когда индекса нет, выполняется полное сканирование: прочитать миллион строк, проверить условие на каждой. Пока таблица маленькая, разница незаметна - поэтому сайт годами работает нормально, а потом каталог вырастает, и та же страница начинает открываться пять секунд. Нагрузка растёт нелинейно: десять одновременных посетителей с тяжёлыми запросами способны занять все ресурсы сервера, довести базу до отказа и до ошибок вида MySQL server has gone away.

Как найти медленные запросы на своём сайте

  1. Включите slow query logВ настройках MySQL или панели хостинга задайте порог, например 1 секунда. Всё, что дольше, попадёт в журнал.
  2. Соберите статистику за 2-3 дняНужна реальная нагрузка: медленные запросы часто всплывают в часы пик или при обходе сайта поисковыми роботами.
  3. Разберите лидеров через EXPLAINКоманда показывает план запроса: полное сканирование видно по type ALL и большому числу просматриваемых строк.
  4. Добавьте индекс и перепроверьтеСоздайте индекс по полям из условий выборки и прогоните EXPLAIN снова: план должен перейти на индекс, время - упасть на порядки.
  5. Повторяйте цикломСняли лидера - смотрите следующего. Обычно 3-5 индексов закрывают большую часть журнала.
Индексы не бесплатны. Каждый индекс замедляет вставку и обновление строк и занимает место на диске: база поддерживает его актуальность при каждой записи. Вешать индексы «на всё подряд, чтобы летало» - вредная стратегия: для магазина с частыми обменами с 1С лишние индексы означают медленные импорты. Добавляйте их точечно, под реальные запросы из журнала.

Найдём, где ползёт ваша база

Включим журнал медленных запросов, разберём план каждого лидера, добавим нужные индексы и покажем время выборок до и после. Аккуратно, с бэкапом и проверкой на копии.

Ускорить базу

Индексы и Битрикс: где чаще всего ползут магазины

Штатные таблицы Битрикс проиндексированы хорошо - проблемы приносят доработки. Классика: умный фильтр по десяткам свойств на большом каталоге, кастомные выборки в шаблонах, написанные без учёта объёмов, отчёты, собирающие данные по всем заказам разом. Отдельная история - highload-блоки: индексы на их полях создаются не сами, о них должен подумать разработчик. Если магазин ощутимо замедлился после роста каталога или очередной доработки - база в списке подозреваемых первая, а как отличить её от других причин, мы разбирали в статье про ошибки базы данных Битрикс.

Техника безопасности. Добавление индекса на большую таблицу может заблокировать её на минуты - на живом магазине это остановленные заказы. Делайте такие операции в тихие часы и после бэкапа, а в идеале - сначала на тестовой копии. Откатить неудачный индекс просто, потерянные заказы вернуть сложнее.

Когда индекс не поможет

Индекс - не панацея. Он бессилен, если запрос ищет подстроку в середине текста, применяет функции к полю в условии или выбирает больше половины таблицы - база резонно решает, что сканирование дешевле. Не спасёт он и при нехватке ресурсов сервера: когда базе не хватает памяти, даже индексированные выборки идут через диск и ползают. В таких случаях лечат сам запрос, архитектуру хранения или тариф хостинга - это уже задача для разработчика, а не для одной команды CREATE INDEX.

Частые вопросы об индексах базы данных

Как понять, что тормозит именно база, а не PHP или фронтенд?
Смотрите на характер тормозов: если медленно открываются страницы с выборками - каталог с фильтром, поиск, отчёты - а статичные страницы летают, подозревайте базу. Точный ответ даёт отладка: время SQL-запросов в мониторе производительности Битрикс или профилировщике видно отдельной строкой.
Сколько индексов можно добавить в одну таблицу?
Технически - десятки, практически - столько, сколько оправдано запросами. Для таблиц с частой записью каждый лишний индекс - налог на вставку. Здоровый ориентир: индексы покрывают реальные условия выборок из журнала, и ни одного «на всякий случай».
Опасно ли добавлять индекс на работающем сайте?
Операция обратимая, но на больших таблицах может заблокировать запись на время построения. Правила простые: бэкап, тихие часы, проверка на копии для таблиц от миллиона строк. При соблюдении этого - процедура рутинная.
Тормозит админка Битрикс, а сайт быстрый - индексы помогут?
Возможно: админские списки с фильтрами по кастомным полям - частый источник медленных запросов. Но у медленной админки есть и другие причины - от нехватки памяти PHP до разросшихся журналов. Начните с монитора производительности: он покажет, куда уходит время.

База данных - фундамент скорости: можно вылизать фронтенд и включить все кэши, но пока выборки сканируют таблицы целиком, сайт будет ползать под нагрузкой. Журнал медленных запросов и EXPLAIN доступны каждому, а если нужен результат без погружения в SQL - передайте задачу нам: в рамках доработки сайтов проведём аудит базы, добавим индексы и перепишем тяжёлые запросы, а на поддержке будем следить за журналом постоянно. Консультация бесплатная, смета за один день.