Включаем кэширование запросов в mysql | FreeBSD, MYSQL

Проверить включено ли кэширование запросов у вас на сервере можно запросом:

mysql> show variables like 'query_cache%';
+------------------------------+-----------+
| Variable_name                | Value     |
+------------------------------+-----------+
| query_cache_limit            | 1048576   |
| query_cache_min_res_unit     | 4096      |
| query_cache_size             | 134217728 |
| query_cache_type             | ON        |
| query_cache_wlock_invalidate | OFF       |
+------------------------------+-----------+
5 rows in set (0.00 sec)


Если query_cache_size = 0, значит кэш не включен.
Чтобы включить кэширование запросов mysql достаточно добавить строки в my.cnf (Секция [mysqld]):

query_cache_size = 268435456
query_cache_type=1
query_cache_limit=1048576

query_cache_limit – определяет максимальный размер результата который попадет в кэш
query_cache_size – размер кэша. Говорят что 256Мб – достаточно, чтобы не сделать обслуживание кэширования слишком «дорогим».

И перезапустить сервис.

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

Попробуем оценить эффект. Смотрим как меняются показания счетчиков попаданий в кэш (Qcahe_hits), количество запросов объявленных недействительными из-за нехватки памяти (Qcache_lowmem_prunes), общее количество запросов типа SELECT (а кэшируются только они). Делаем:

#mysq -u root -p
mysql> show status like 'Qcache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 715       |
| Qcache_free_memory      | 130369640 |
| Qcache_hits             | 24209     |
| Qcache_inserts          | 16215     |
| Qcache_lowmem_prunes    | 0         |
| Qcache_not_cached       | 444       |
| Qcache_queries_in_cache | 1740      |
| Qcache_total_blocks     | 4225      |
+-------------------------+-----------+
8 rows in set (0.00 sec)

Это пример «неразогретого» кэша на сервере под нагрузкой. Движок – форум на IPB. Qcache_inserts – записи которые записываются в кэш, Qcache_not_cached – не кэшируемые запросы, Qcache_lowmem_prunes – выгруженых запросов по причине нехватки памяти пока нет, Qcache_free_blocks – количество выделенных блоков (будет уменьшаться по мере увеличения скэшированных запросов).

Можно просмотреть общее количество запросов SELECT:

mysql> show status like 'Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    | 16719 |
+---------------+-------+
1 row in set (0.00 sec)

Оценивать эффективность кэша рекомендуют делением значения переменной Qcache_hits на Qcache_hits + Com_select, поскольку при обработке запроса увеличивается счётчик Qcache_hits (если запрос обработан из кэша) или Com_select (если запрос не кэширован). Такой способ предлагают в «Mysql оптимизация производительности» O’reilly

В сети есть другой способ – Qcache_hits / (Qcache_inserts + Qcache_not_cached). Перед этим наверное стоит выполнить сброс всех счётчиков командой FLUSH STATUS.

Если счетчик Qcache_not_cached велик, можно попробоавть увеличить переменную query_cache_limit – она позволит увеличить лимит и помещать в кэш результаты запросов которые «не помещаются».

Вот пример сервера с базой CMS Joomla!
Здесь эффект от кэширования более очевиден:

mysql> show status like 'Qcache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 495       |
| Qcache_free_memory      | 261073328 |
| Qcache_hits             | 927531    |
| Qcache_inserts          | 300901    |
| Qcache_lowmem_prunes    | 0         |
| Qcache_not_cached       | 18581     |
| Qcache_queries_in_cache | 2172      |
| Qcache_total_blocks     | 5004      |
+-------------------------+-----------+
8 rows in set (0.00 sec)

mysql> show status like 'Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select    | 1     |
+---------------+-------+
1 row in set (0.00 sec)

Дефрагментировать кэш можно командой:

mysql>flush query cache;

Очистить – командой:

mysql>reset query cache;

  1. FreeBSD под рукой нет, но на CentOS5 + mysql-server-5.5.19 данные параметры оказывается были по дефолту. Не помню что бы я их добавлял.
    Спасибо что напомнили, протестирую на более нагруженном сервере.