#Что означает неисправность и в каких условиях возникает
После обновления MySQL/Percona один SQL-запрос стал выполняться медленнее: в EXPLAIN изменился план доступа к таблице, пропал прежний индекс или выросло количество просматриваемых строк. Причиной может быть изменение оценок оптимизатора, статистики или самого SQL, а не поломка индекса. Не принуждайте использование индекса до сравнения планов на сходных данных: полный просмотр таблицы может быть быстрее при большой доле подходящих строк.
#Возможные причины: как различить
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Устаревшие оценки распределения значенийПосле переноса или обновления статистика не отражает реальные данные. | EXPLAIN показывает прежний key=NULL или резкую смену rows; данные существенно изменились. | Проверить статистику и согласовать ANALYZE TABLE. |
| Изменились значения и условия WHEREНовый запрос использует функцию на столбце, другое сравнение или тип данных. | Текст запроса или тип параметров отличается от прежнего. | Вернуть условие, совместимое с индексом, после теста на копии. |
| Оптимизатор выбрал другой планНовая версия оценивает стоимость иначе. | Есть индекс, но key отличается; план на той же копии данных другой. | Сравнить версии и планы, проверить реальные времена и индексы. |
#Пошаговая диагностика и устранение
- Зафиксируйте версию и конкретный запросВ mysql на сервере выполните
SELECT VERSION();, сохраните дату обновления и полный текст проблемного SELECT без личных данных. Сравните его с прежней версией из контроля исходного кода; если поменялись WHERE или JOIN, это уже отдельная причина. Не запускайте дорогой запрос многократно в пик ради измерения. - Снимите безопасный план без выполненияДля проблемного SELECT на испытательной копии запустите
EXPLAIN SELECT ...;, подставив фактический запрос. Обычный EXPLAIN для SELECT показывает предполагаемый план; EXPLAIN ANALYZE действительно выполняет запрос, поэтому для тяжёлой боевой таблицы без оценки риска его не используйте. - Сравните колонки планаВ традиционном EXPLAIN смотрите
type,possible_keys,key,rows,Extra.possible_keysперечисляет кандидатов,keyпоказывает выбранный индекс; значение NULL означает, что индекс не используется для указанного доступа. Сопоставьте старый и новый планы на максимально близком размере данных и одинаковом SQL. - Убедитесь в наличии индекса и правильных типахВ mysql выполните
SHOW INDEX FROM имя_таблицы;с вашим реальным именем, если можете безопасно прочитать структуру. Сравните индексируемые столбцы с JOIN/WHERE и типами соединяемых полей. Функция вокруг столбца, несовпадение строковых наборов или типизация параметра способны ухудшить использование индекса. - Проверьте актуальность статистикиПосле резервной копии и оценки нагрузки на копии базы DBA может выполнить
ANALYZE TABLE имя_таблицы;для обновления статистики. Операция анализирует распределение ключей, способна брать блокировки и обычно записывается в бинарный журнал. На боевой базе проводите её в согласованное время, не рассматривайте как абсолютно бесплатную команду. - Сравните план до и после анализаПовторите EXPLAIN тем же SELECT и параметрами. Если
keyиrowsизменились, проверьте фактическую длительность в изолированной копии и число возвращённых строк. Если план не изменился, не повторяйте ANALYZE TABLE циклически: нужны другие сведения о распределении и оптимизаторе. - Попробуйте правку запроса на копииПерепишите фильтр так, чтобы индексируемое поле использовалось напрямую, без ненужных CAST/функций. Проверьте равенство результата старой и новой формулировки на тестовых данных. Добавление нового индекса или FORCE INDEX обсуждайте только после сравнения планов и стоимости записей; индекс сам по себе увеличивает затраты на обновление.
- Сохраните способ отката и измерьте эффектВыпустите исправление запроса обычным развёртыванием с возможностью отката версии; для схемы нужна отдельная резервная копия и миграция назад. Снимите время выполнения и количество чтений за одинаковое окно нагрузки. Если оптимизация ухудшила другой запрос, отмените изменение и разберите его план отдельно.
- Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Как проверить исправление и что делать, если оно не помогло
Успех — на одинаковых данных время выбранного SELECT снизилось, план объясним, строки результата не изменились, побочных регрессий в других запросах нет. Если после обновления статистики план всё ещё плох, соберите EXPLAIN, SHOW INDEX и версии сервера для DBA; не откатывайте всё обновление без оценки безопасности и совместимости.