6.9.1 Как работает кэширование запросов
Перед синтаксическим анализом запросы сравниваются, поэтому запросы
SELECT * FROM TABLE
и
Select * from table
для кэша запросов рассматриваются как различные, поскольку они должны быть
абсолютно одинаковыми (байт в байт), чтобы рассматриваться как идентичные.
Помимо этого, запрос может трактоваться как отличающийся, если, например,
какой-либо клиент использует протокол соединения нового формата или иной
набор символов, чем другой клиент.
Запросы, использующие различные базы данных, различные версии протоколов
или различные наборы символов по умолчанию, рассматриваются как различные
и кэшируются раздельно.
Рассматриваемый кэш надежно работает для запросов вида SELECT CALC_ROWS
...
и SELECT FOUND_ROWS() ...
, так как число найденных строк всегда
хранится в кэше.
При изменениях таблицы (INSERT
, UPDATE
, DELETE
, TRUNCATE
, ALTER
или DROP
TABLE|DATABASE
), все кэшированные запросы, использовавшие данную таблицу
(возможно, через таблицу MRG_MyISAM
!), становятся недействительными и
удаляются из кэша.
Если изменения были произведены в поддерживающих транзакции таблицах вида
InnoDB
, то все кэшированные запросы становятся недействительными при
выполнении команды COMMIT
.
Запрос не будет кэширован, если содержит одну из приведенных ниже функций:
Функция
| Функция
| Функция
|
Определяемые пользователем функции (UDF)
| CONNECTION_ID
| FOUND_ROWS
|
GET_LOCK
| RELEASE_LOCK
| LOAD_FILE
|
MASTER_POS_WAIT
| NOW
| SYSDATE
|
CURRENT_TIMESTAMP
| CURDATE
| CURRENT_DATE
|
CURTIME
| CURRENT_TIME
| DATABASE
|
ENCRYPT (с одним параметром)
| LAST_INSERT_ID
| RAND
|
UNIX_TIMESTAMP (без параметров)
| USER
| BENCHMARK
|
Запрос также не будет кэширован, если он содержит переменные пользователя
или выражен в форме SELECT ... IN SHARE MODE
или в форме SELECT * FROM
AUTOINCREMENT_FIELD IS NULL
(для полечения последнего ID - это для ODBC).
Однако FOUND ROWS()
возвратит правильную величину, даже если из кэша был
выбран предыдущий запрос.
Также не кэшируются запросы, не использующие какие-либо таблицы, или если
пользователь имеет какие-либо привилегии для столбцов использованных
таблиц.
Перед выборкой запроса из кэша запросов MySQL проверит, обладает ли
пользователь привилегией SELECT
для всех включенных баз данных и таблиц.
Если это не так, то результат кэширования не используется.