Mysql замедляет первый запрос, затем быстро для связанных запросов

Я борется с проблемой, которая возникает только тогда, когда база данных простаивает в течение определенного периода времени для запрошенных данных. Первый запрос будет очень медленным, порядка 30 секунд, а затем связанные запросы будут быстрыми, как 0,1 секунды. Я предполагаю, что это связано с кэшированием, но я не смог найти причину этого.

Изменение переменных mysql tmp_table_size, max_heap_table_size для большего размера не имело эффекта, кроме создания временных таблиц в памяти.

Я не думаю, что это связано с самим запросом, так как он хорошо проиндексирован и после первого медленного запроса варианты одного и того же запроса не отображаются в журнале медленных запросов. Я больше всего заинтересован в том, чтобы определить причину этого или способ reset оскорбительного кеша, чтобы я мог устранить проблему.

Ответ 1

Страницы файлов данных innodb получают кеширование в пуле буферов innodb. Это то, что вы ожидаете. Чтение файлов происходит медленно, даже на хороших жестких дисках, особенно случайных чтениях, которые в основном показывают базы данных.

Возможно, ваш первый запрос выполняет какое-то сканирование таблицы, которое тянет много страниц в пул буферов, а затем быстрый доступ к ним. Или что-то подобное.

Это то, что я ожидаю.

В идеале используйте один и тот же движок для всех таблиц (исключения: системные таблицы, временные таблицы (возможно) и очень маленькие таблицы или недолговечные). Если вы этого не сделаете, им придется сражаться за барана.

Предполагая, что все ваши таблицы являются innodb, заставьте буферный пул использовать до 75% от физического RAM сервера (при условии, что вы не запускаете слишком много других задач на машине).

Затем вы сможете поместиться вокруг 12G вашей базы данных в ram, поэтому, когда он "разогреется", "наиболее используемый" 12G вашей базы данных будет в ram, где доступ к нему будет приятным и быстрым.

Некоторые пользователи mysql имеют тенденцию "разминать" производственные серверы после перезагрузки, отправив им запросы, скопированные с другой машины на некоторое время (это будут подчиненные репликации), пока они не добавят их в свой производственный пул. Это позволяет избежать экстремальной медлительности, наблюдаемой во время холода кеша. Например, Youtube делает это (или, по крайней мере, он использовал, Google купил их, и теперь они могут использовать Google-fu)

Ответ 2

Что-нибудь еще работает на вашем сервере mysql? Моя мысль заключается в том, что, возможно, после первого запроса ваша таблица все еще кэшируется в памяти. Когда он простаивает, другой процесс вызывает его кэширование. Просто предположим, хотя.

Сколько памяти у вас есть, что еще работает?

Ответ 3

У меня был пакет SSIS, который отключился. Запрос был очень простым: из одной таблицы MySQL, но иногда он возвращал много записей и иногда выполнял несколько минут, чтобы выполнить, а затем только несколько миллисекунд после этого, если я захочу снова запросить его. Мы застряли в соединении ADO, что означало, что он истечет через 30 секунд, поэтому около половины баз данных, которые мы пытались загрузить, терпели неудачу.

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

Ответ 4

Ttry и сравните вывод "vmstat 1" в командной строке linux при запуске запроса через определенный промежуток времени, а также при повторном запуске и быстро получить результаты. В частности, проверьте столбец "bi" (чтение kb с диска в секунду).

Вы можете обнаружить, что операционная система кэширует блоки диска в быстром случае (и, следовательно, низкую цифру "bi" ), но не в медленном случае (и, следовательно, большую цифру "bi" ).

Вы также можете обнаружить, что vmstat показывает использование высоких/низких CPU в любом случае. Если он низкий, когда он быстрый, а пропускная способность диска также низкая, ваша система все равно может возвращать кешированный запрос, даже если вы указали, что соответствующее значение конфигурации установлено на ноль. Возможно, проверьте вывод show engine innodb status и SHOW VARIABLES и подтвердите.

innodb_buffer_pool_size также может быть установлен высоко (он должен быть...), который будет кэшировать блоки еще до того, как ОС сможет их вернуть.

Вы также можете обнаружить, что "key_buffer" установлен на высокий уровень - это будет кэшировать ключи в индексах, что может сделать ваш выбор ослепляюще быстрым.

Попробуйте сайт mysql performance для получения большой полезной информации.

Ответ 5

У меня возникла проблема, когда MySQL 5.6 был медленным при первом запросе после периода ожидания. Это проблема подключения, а не проблема экземпляра MySQL, например. если вы запустите MYSQL Query Browser, выполните "select * from some_queue", оставьте его в покое на пару часов, затем выполните любой запрос, он работает медленно, в то время как процессы на сервере или новом экземпляре браузера будут выбирать из одних и тех же таблиц мгновенно.

Добавление кэша skip-host-cache, skip-name-resolve в файл my.ini решило эту проблему.

Я не знаю, почему. Почему я это пробовал: MySQL 5.1 без этих параметров медленно устанавливал соединения из других сетей (например, сервер 192.168.1.100, 192.168.1.101 подключается быстро, 192.168.2.100 подключается медленно), MySQL 5.6 не имел такой проблемы, чтобы начать с так мы не добавили их в my.ini изначально.

UPD: на самом деле разрешили половину случаев. Установка wait_timeout в максимальное целое фиксирует вторую половину. Может быть, я даже сейчас могу удалить skip-host-cache, skip-name-resolve и не будет замедляться в 100% случаев.

Ответ 6

Workbench MySQL:

Ниже приведено не 100%, связанное с этим вопросом SO, но симптомы очень взаимосвязаны, и это первый результат SO при поиске "mysql workbench slow" или связанных терминов, поэтому, надеюсь, это полезно для других.

Очистить историю запросов! - после процесса в истории запросов mysql mysql (последний выполненный запрос/запрос), т.е. создать/изменить таблицу, выбрать, вставить обновить запросы, чтобы очистить историю запросов MySQL Workbench, действительно ускорило мою программу.

В итоге: измените область Output на History Output, щелкните правой кнопкой мыши по дате и выберите Delete All Logs.

Проблема, с которой я столкнулся, заключалась в "медленном первом запросе", поскольку для загрузки результатов потребовалось бы несколько секунд, даже если длительность/выборка были в пределах 1 секунды. После очистки истории запросов время продолжительности/выборки оставалось прежним (примерно 1 секунда, поэтому поведение DB не изменилось), но теперь результаты загружаются мгновенно, а не после нескольких секунд задержки.