Запрос кэшируется при локальной настройке, но никогда на сервере?

У меня много проблем с кешем запросов в проекте: я использую Percona-вкус MySQL, такие же версии как на моей локальной машине разработки, так и на рабочем сервере. Теперь включение кеша запросов дает мне отличные результаты на моей локальной машине: практически все запросы, которые нужно кэшировать, эффективно.

Теперь точно такие же запросы не кэшируются на рабочем сервере. Все точно так же; переменные mysql, содержимое базы данных, кодовая база, зарегистрированный пользователь, но при производстве кэшируются только несколько запросов, причем самые важные из них пропускаются. И я не могу понять, почему: -)

Итак, ища решение, я работаю со следующим запросом, используемым для выбора последних 3 тем из таблицы тем: (это самый "тяжелый" запрос и тот, который я определенно хочу кэшировать! )

SELECT `topic`.* FROM `topics` AS `topic` 
LEFT OUTER  JOIN `topics` AS `topic_helper` 
 ON (`topic`.`id` = `topic_helper`.`id` 
      AND `topic_helper`.`created_on` < `topic`.`created_on`) 
GROUP BY `topic`.`id` HAVING COUNT(*) < 3 
ORDER BY `topic`.`created_on` DESC;

Итак, для начала SHOW VARIABLES LIKE '%query_cache% дают мне те же результаты, что и локальные, как и при производстве:

+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| have_query_cache             | YES      |
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 10485760 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

Выполнение вышеуказанного запроса будет кэшироваться локально после первого запуска, так как SHOW PROFILE ясно сообщает мне ближе к концу трассировки:

| Waiting for query cache lock   | 0.000001 |
| Waiting on query cache mutex   | 0.000001 |
| freeing items                  | 0.000000 |
| storing result in query cache  | 0.000002 |
| logging slow query             | 0.000001 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+

Второй вызов возвращает запрос из кэша, как и ожидалось.

На рабочем сервере запуск этого запроса никогда не будет храниться в кеше. Результирующий набор точно такой же, и явно не используются никакие операторы, которые могут привести к аннулированию кеширования запросов (согласно руководству в http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html - Я уверен, что указанный выше запрос соответствует требованиям для его кэширования.)

Для полноты полноты полный вывод SHOW PROFILE для того же запроса на производственном сервере вставляется здесь: http://pastebin.com/7Jm5rmVd

Кроме того, стоит отметить, что, хотя конфигурация на обоих серверах абсолютно одинакова, моя локальная версия - 5.5.27, немного более новая, чем та, что была в версии 5.5.17-55. Может быть, это проблема..?

Я сравнил полный вывод SHOW VARIABLES; с моего локального сервера как с производственным сервером, чтобы увидеть, не пропало ли что-либо, но ничего не отличается, кроме системного часового пояса и пути к файлам журналов и т.д.

Итак, может кто-нибудь из вас знает, где искать дальше? Или можете понять, что может быть причиной этого?

Ответ 1

Мы много используем сервер Percona, а также сообщество MySQL.

Кэши запросов являются мощными и сильно сложными. Хуже того, что MySQL может сделать, это вернуть некоторые устаревшие данные кеша.

Не только MySQL кэширует запросы, но также и данные базы данных - и использует индексы для дополнительной производительности.

Все, что может привести к аннулированию кеша запроса, делает его недействительным.

Как правило, мы не слишком внимательно относимся к тому, кэшируется ли он или нет... мы верим, что MySQL действует разумно - если по какой-либо причине он считает, что что-то не следует кэшировать, кешируйте его. Тем не менее, мы делаем так, чтобы наши запросы были максимально эффективными и простыми.

Если я могу это сказать, я думаю, что вы столкнетесь с серьезными проблемами масштабируемости независимо от кеша запроса, если ваш примерный запрос является "одним из наиболее используемых". Он будет работать как собака без ног, как только этот сервер будет занят!

В соответствии с вашей записью pastebin - вы создаете хотя бы одну временную таблицу, возможно, из-за внешнего соединения (или GROUP BY).

Я все для нормализации, но иногда производительность требует альтернативного маршрута.

Не можете ли вы кэшировать некоторые из этих данных самостоятельно, в какой-то таблице поиска/сводки? Триггеры могут быть вашим другом здесь:)