Добрый вечер!
Подскажите, почему может происходить следующая ситуация (и куда копать?):
выполняю запрос, выдаёт:
Query took 3.8722 seconds
тут же запускаю снова, пишет:
Query took 0.0001 seconds
Жду ~12–13 секунд, запускаю и снова всё повторяется по кругу.
Пример запроса (есть похожие с таким же поведение, не только этот):
На всякий случай из mysqltuner-овского:
.
UPD в качестве анализа для коллег, обслуживающих сайты на Битрикс:
выборка в примере производится из таблицы с разделами, таблицы с элементами и пары вспомогательных таблиц со свойствами. В Битриксе все разделы, которые только есть на сайте, льются в общую таблицу и все элементы, которые только есть на сайте льются в общую таблицу. Исходя из
описания, а также обращая отдельное внимание на:
«
Отдельно обрабатывается кеширование выборок от InnoDB таблиц. MySQL удаляет результаты выборок из кеша при любом изменении таблицы (уточню: изменение в любой из таблиц) внутри транзакции»
...приходим к следующим умозаключениям:
1. Таблица с разделами по-идее не должна обновляться так активно, как другие таблицы. Если наблюдается странное поведение запроса — где-то в самой таблице обновляется какой-то счётчик (например комментариев или просмотров). Странное поведение в работе практически не поймать (никто не долбит страницы с
?clear_cache=Y, пытаясь понять, как ведут себя запросы), а вот при проектировании или анализе инфоблока можно наткнуться на то, что в каком-то из полей хранится счётчик (даже иногда в стандартных полях типа CODE или SORT). От такого нужно избавляться (выносить в hl-блоки, использовать ORM или лить в статику).
2. В случае с элементами аналогично. Тут дополнительно напрашиваются ещё как пример: есть «стандартное» поле для хранения количества комментариев (его появление растёт из модуля форумов):
FORUM_MESSAGE_CNT. Если мы выполняем выборку элементов вместе с выборкой значения данного поля, может возникнуть такая ситуация, когда у нас элемент не обновляется, а кеш сбрасывается, потому что в запросе идёт связка с таблицей, хранящей счётчик. Стоит проанализировать и возможно делать выборку двумя отдельными запросами.
3. Активно используем HL-блоки и ORM, чтобы разбить эти две общие таблицы на независимые части.
4. Нагрузка и ситуация, описанная в примере, была вызвана тем, что в компоненте был установлен чекбокс «
Отображать количество элементов» (производится подсчёт, сколько элементов содержится в каждой из таблиц в выборке). При чём формировалось практически два одинаковых запроса: непосредственно выборка разделов и счётчик (COUNT) по элементам. Если вам не нужен этот счётчик — отключайте. Из опыта, он в 99% случаев нужен только в админке. Либо если он нужен, выкручиваться отдельной базой счётчиков, которая обновляется по событию (добавление / обновление / удаление элементов). Пересчитали именно тогда, когда нужно, и потом пользуемся статистикой.