Вам слід просто відключити кеш запитів за допомогою
[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), або тому, що її набір результатів занадто великий для зберігання.
- Сервер ніколи раніше не бачив запит, тому у нього ніколи не було можливості кешувати його результат.
- Результат запиту раніше був кешований, але сервер його видалив. Це може статися тому, що не вистачало пам'яті, щоб зберегти його, тому що хтось доручив серверу видалити його або тому, що він був визнаний недійсним
і першопричинами помилок у високому кеші з кількома запитами, які не підлягають керуванню, можуть бути:
- Кеш запитів ще не нагрітий. Тобто сервер не мав шансу заповнити кеш наборами результатів.
- Сервер бачить запити, яких раніше не бачив. Якщо у вас немає багато повторних запитів, це може статися навіть після прогрівання кеша.
- Існує дуже багато виправлень кешу.
ОНОВЛЕННЯ 2012-09-06 10:10 EDT
Переглядаючи останню оновлену інформацію, ви query_cache_limit
встановили 1048576 (1М). Це обмежує будь-який результат, встановлений на 1М. Якщо ви отримаєте щось більше, воно просто не буде кешоване. Хоча ви query_cache_size
встановили 104857600 (100 М), це дозволяє лише 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 = 8М
Це залишає 23G оперативної пам’яті. Я хотів би зазначити наступне:
- innodb_buffer_pool_size = 12G
- key_buffer_size = 4G
Це залишає 7G. Це повинно бути достатнім для підключень ОС та БД.
Майте на увазі, що буфер ключів кешує лише індексні сторінки MyISAM, тоді як InnoDB Buffer Pool кешує дані та індекси.
Ще одна рекомендація: оновлення до MySQL 5.5, щоб ви могли налаштувати InnoDB для декількох процесорів і декількох потоків для читання / запису вводу / виводу.
Дивіться мої попередні повідомлення про використання MySQL 5.5 спільно з доступом до декількох процесорів для InnoDB
ОНОВЛЕННЯ 2012-09-06 14:56 EDT
Мій метод очищення кешу запитів досить екстремальний, оскільки він збирає кешовані дані та утворює зовсім інший сегмент ОЗУ. Як ви вказували у своєму коментарі FLUSH QUERY CACHE
(як ви запропонували) або навіть RESET QUERY CACHE
було б краще. Для уточнення, коли я сказав «немає внутрішнього механізму», я мав на увазі саме це. Дефрагментація потрібна і повинна бути виконана вручну. Це потрібно було б бути crontab'd .
Якщо ви робите DML (INSERT, UPDATE, DELETE) на InnoDB частіше, ніж на MyISAM, я б сказав, що виймаєте кеш запитів взагалі, про що я говорив на початку.