MySQL кеширует запросы?

19

Я связываю базу данных MySQL с объектами данных PHP (PDO) и выполняю обширный SQL-запрос. Обычно это занимает около 1500 мс; Я все еще должен оптимизировать это. Когда я дважды запускаю PHP-скрипт с небольшим интервалом, запрос занимает около 90 мс. Запрос в обоих случаях одинаков. Когда я запускаю сценарий с тем же запросом, через некоторое время это снова занимает 1500 мс.

Это почему? Кеширует ли база данных автоматически? Некоторое время база данных сохраняет кеш, а затем автоматически удаляет его?

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

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

Питер Мортенсен
источник
Покажи мне свой код. Мне не нужен ваш запрос, просто способ, которым вы его тестируете.
3
Да, MySQL кеширует запросы. Это так умно.
@ Kasyx какой код? Это просто базовый PDO, но я не думаю, что PHP может его кешировать, потому что я запускаю PHP-скрипт дважды, я не запускаю запрос дважды в одном скрипте. Также не могли бы вы объяснить, почему вы редактировали pdo, хотя это не имеет отношения к вопросу?
3
Все СУБД имеют некоторый кеш на уровне страниц. Многие выходят за рамки этого, кэшируя планы выполнения запросов или даже результаты запросов (включая MySQL ). Я подозреваю, что это последнее, что является основным виновником вашего наблюдаемого поведения.
Бранко Димитриевич
Вы делаете вставки каждую минуту? Сортировка , что из первых!
Грант Томас

Ответы:

15

Вероятно, это артефакт MySQL Query Cache .

Вы выполняете запрос SQL, MySQL кэширует его результат и следующее выполнение, если это быстро. Когда вы запускаете сценарий для вставки данных в таблицы, на которые ссылается ваш запрос, кэш результатов становится недействительным, и в следующий раз запрос должен быть выполнен «по-настоящему».

Из документации по MySQL, указанной выше:

Комбинация запросов, состоящая почти полностью из фиксированного набора операторов SELECT, с большей вероятностью выиграет от включения кэша, чем смесь, в которой частые операторы INSERT вызывают постоянную аннулирование результатов в кэше.

Бранко Димитриевич
источник
5

Да, mySQL (как и все другие популярные продукты баз данных) кэширует запросы, которые к нему сделаны.

Кэширование довольно умно - оно часто может использовать кеш для запроса, даже если точные параметры запроса не совпадают. Это может иметь большое значение для производительности.

Кэширование полностью контролируется внутри программного обеспечения сервера БД; у вас нет никакой видимости того, что содержит кеш, и как долго данный элемент остается в кеше; он может быть перезаписан в любой момент в зависимости от того, какие другие запросы вызываются и т. д. Он предназначен для повышения производительности, но на производительность не следует полагаться.

Вы можете прочитать больше об этом здесь в руководстве MySQL .

Кроме того, использование PDO позволяет записывать ваши запросы как «Подготовленные операторы», связывая параметры, а не жестко кодируя их в виде строки простого текста. Это также имеет значение для кэширования на сервере БД и для повторяющихся запросов также повысит производительность.


источник
2
«Начиная с MySQL 5.1.17, кэш запросов используется для подготовленных операторов в условиях, описанных в разделе 8.6.3.1,« Как работает кэш запросов ». До 5.1.17 кэш запросов не использовался для подготовленных операторов». dev.mysql.com/doc/refman/5.1/ru/query-cache.html
1
« Как и все другие популярные продукты баз данных »: это немного вводит в заблуждение. Вряд ли какая-либо СУБД активно кэширует результаты запросов, как это делает MySQL. СУБД обычно только кэш таблица (или индекс) данные , а не результаты запроса . Большинство из них кэшируют план выполнения запроса (и запрос «источник»)
a_horse_with_no_name
3
«он часто может использовать кеш для запроса, даже если точные параметры запроса не совпадают» совершенно неверно. Запрос должен быть побайтовым, идентичным ранее выполненному и все еще кэшированному запросу, чтобы его можно было обслуживать из кэша. Даже разница между SELECT *и select *означает, что в противном случае идентичный запрос не будет обслуживаться из кэша. dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html . Выложена ссылка 5.1 для согласованности, но относится ко всем версиям.
Майкл - sqlbot