AlexeyGfi
@AlexeyGfi
YouTube >>> Битриксоид из Колхоза

Mysql: почему может прыгать скорость выполнения запроса?

Добрый вечер!

Подскажите, почему может происходить следующая ситуация (и куда копать?):
выполняю запрос, выдаёт:
Query took 3.8722 seconds
тут же запускаю снова, пишет:
Query took 0.0001 seconds

Жду ~12–13 секунд, запускаю и снова всё повторяется по кругу.

Пример запроса (есть похожие с таким же поведение, не только этот):
09065e5f60cc450cb0ae0c8aaf1bb87b.jpg

На всякий случай из mysqltuner-овского:
8cbfc5f4fbd944ada427c6fee283d50e.jpg
.

UPD в качестве анализа для коллег, обслуживающих сайты на Битрикс:
выборка в примере производится из таблицы с разделами, таблицы с элементами и пары вспомогательных таблиц со свойствами. В Битриксе все разделы, которые только есть на сайте, льются в общую таблицу и все элементы, которые только есть на сайте льются в общую таблицу. Исходя из описания, а также обращая отдельное внимание на:
«Отдельно обрабатывается кеширование выборок от InnoDB таблиц. MySQL удаляет результаты выборок из кеша при любом изменении таблицы (уточню: изменение в любой из таблиц) внутри транзакции»
...приходим к следующим умозаключениям:

1. Таблица с разделами по-идее не должна обновляться так активно, как другие таблицы. Если наблюдается странное поведение запроса — где-то в самой таблице обновляется какой-то счётчик (например комментариев или просмотров). Странное поведение в работе практически не поймать (никто не долбит страницы с ?clear_cache=Y, пытаясь понять, как ведут себя запросы), а вот при проектировании или анализе инфоблока можно наткнуться на то, что в каком-то из полей хранится счётчик (даже иногда в стандартных полях типа CODE или SORT). От такого нужно избавляться (выносить в hl-блоки, использовать ORM или лить в статику).

2. В случае с элементами аналогично. Тут дополнительно напрашиваются ещё как пример: есть «стандартное» поле для хранения количества комментариев (его появление растёт из модуля форумов): FORUM_MESSAGE_CNT. Если мы выполняем выборку элементов вместе с выборкой значения данного поля, может возникнуть такая ситуация, когда у нас элемент не обновляется, а кеш сбрасывается, потому что в запросе идёт связка с таблицей, хранящей счётчик. Стоит проанализировать и возможно делать выборку двумя отдельными запросами.

3. Активно используем HL-блоки и ORM, чтобы разбить эти две общие таблицы на независимые части.

4. Нагрузка и ситуация, описанная в примере, была вызвана тем, что в компоненте был установлен чекбокс «Отображать количество элементов» (производится подсчёт, сколько элементов содержится в каждой из таблиц в выборке). При чём формировалось практически два одинаковых запроса: непосредственно выборка разделов и счётчик (COUNT) по элементам. Если вам не нужен этот счётчик — отключайте. Из опыта, он в 99% случаев нужен только в админке. Либо если он нужен, выкручиваться отдельной базой счётчиков, которая обновляется по событию (добавление / обновление / удаление элементов). Пересчитали именно тогда, когда нужно, и потом пользуемся статистикой.
  • Вопрос задан
  • 326 просмотров
Решения вопроса 1
@maxtm
Make money, not job
У Вас просто используется кэш запросов, со временем он протухает и запрос вновь медленно выполняется.
Попробуйте выполнить запрос без кэширования, будете видеть "настоящее" время выполнения.
SELECT SQL_NO_CACHE ...
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы