Вы должны просто отключить кеш запросов с помощью
[mysqld]
query_cache_size = 0
и затем перезапустите MySQL. Зачем мне это предлагать ???
Кэш запросов всегда будет бодаться с InnoDB. Было бы хорошо, если бы MVCC InnoDB позволял обрабатывать запросы из кеша запросов, если изменения не влияют на повторяющиеся операции чтения для других транзакций. К сожалению, InnoDB просто не делает этого. Очевидно, у вас есть много запросов, которые довольно быстро становятся недействительными и, вероятно, не используются повторно.
Для InnoDB под MySQL 4.0 кеш запросов был отключен для транзакций. Для MySQL 4.1+ InnoDB проигрывает данные трафика, когда разрешает доступ к кешу запросов для каждой таблицы.
С точки зрения вашего вопроса, я бы сказал, что оправдание удаления кэша запросов - это не столько накладные расходы, сколько то, как InnoDB управляет этим.
Для получения дополнительной информации о том, как InnoDB взаимодействует с кешем запросов, пожалуйста, прочитайте страницы 213-215 книги «Высокопроизводительный MySQL (второе издание)» .
Если все или большинство ваших данных являются MyISAM, вы можете использовать свою исходную идею использования SQL_NO_CACHE.
Если у вас есть сочетание InnoDB и MyISAM, вам нужно будет найти правильный баланс для вашего приложения в зависимости от того, насколько высоки ваши потери в кеше. На самом деле, страницы 209-210 этой же книги указывают на причины пропуска кэша:
- Запрос не может быть кэширован либо потому, что он содержит недетерминированную конструкцию (например, CURRENT_DATE), либо потому, что его набор результатов слишком велик для хранения. Оба типа не кэшируемых запросов увеличивают переменную состояния Qcache_not_cached.
- Сервер никогда не видел запрос раньше, поэтому у него никогда не было возможности кэшировать его результат.
- Результат запроса ранее был кэширован, но сервер удалил его. Это может произойти из-за недостатка памяти для хранения, из-за того, что кто-то дал команду серверу удалить его, или потому что он был признан недействительным.
и основными причинами большого количества кеш-пропусков с небольшим количеством некэшируемых запросов могут быть:
- Кеш запросов пока не прогрелся. То есть у сервера не было возможности заполнить кэш наборами результатов.
- Сервер видит запросы, которых раньше не видел. Если у вас мало повторяющихся запросов, это может произойти даже после прогрева кеша.
- Есть много недействительных кеша.
ОБНОВЛЕНИЕ 2012-09-06 10:10 ПО ВОСТОЧНОМУ ВРЕМЕНИ
Просматривая вашу последнюю обновленную информацию, вы query_cache_limit
установили 1048576 (1M). Это ограничивает любой результат до 1M. Если вы получите что-то большее, оно просто не будет кэшировано. Хотя вы query_cache_size
установили значение 104857600 (100M), это позволяет использовать только 100 кэшированных результатов в идеальном мире. Если вы выполните сотни запросов, фрагментация произойдет довольно быстро. У вас также есть 4096 (4K) в качестве минимального набора результатов. К сожалению, в mysql нет внутреннего механизма дефрагментации кеша запросов.
Если у вас должен быть кэш запросов и у вас так много оперативной памяти, вы можете выполнить следующее:
SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;
для того, чтобы очистить кеш запросов. Вы теряете все кэшированные результаты, поэтому запускайте эти строки в непиковые часы.
Я бы также назначил следующее:
- query_cache_size = 1G
- query_cache_limit = 8M
Это оставляет 23 ГБ ОЗУ. Я хотел бы поднять следующее:
- innodb_buffer_pool_size = 12G
- key_buffer_size = 4G
Это оставляет 7G. Это должно быть достаточно для соединений с ОС и БД.
Помните, что буфер ключей кэширует только страницы индекса MyISAM, а пул буферов InnoDB кэширует данные и индексы.
Еще одна рекомендация: обновите MySQL до 5.5, чтобы можно было настроить InnoDB для нескольких процессоров и нескольких потоков для операций ввода-вывода с возможностью чтения / записи.
Смотрите мои предыдущие посты об использовании MySQL 5.5 в сочетании с доступом к нескольким процессорам для InnoDB
ОБНОВЛЕНИЕ 2012-09-06 14:56 ПО ВОСТОЧНОМУ ВРЕМЕНИ
Мой метод очистки кэша запросов довольно экстремальный, потому что он хранит кэшированные данные и образует совершенно другой сегмент оперативной памяти. Как вы указали в своем комментарии, FLUSH QUERY CACHE
(как вы предложили) или даже RESET QUERY CACHE
будет лучше. Для пояснения, когда я сказал «нет внутреннего механизма», я имел в виду именно это. Дефрагментация необходима и должна быть сделана вручную. Это должно быть crontab'd .
Если вы выполняете DML (INSERT, UPDATEs, DELETEs) на InnoDB чаще, чем на MyISAM, я бы сказал, что нужно вообще удалить кеш запросов, о чем я говорил в начале.