Archive

Posts Tagged ‘mysql optimization’

Mysql Query Cache Optimization Review

November 5, 2014 Leave a comment

Query Cache:

my.cnf:
query_cache_type = 1
query_cache_size = 20M
query_cache_limit = 1M

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 537      |
| Qcache_free_memory      | 14197176 |
| Qcache_hits             | 24170    |
| Qcache_inserts          | 4697     |
| Qcache_lowmem_prunes    | 0        |
| Qcache_not_cached       | 68       |
| Qcache_queries_in_cache | 2895     |
| Qcache_total_blocks     | 6481     |
+-------------------------+----------+
8 rows in set (0.00 sec)

Query Cache Formulas:

Query cache hit rate = ((Qcache_hits / (Qcache_hits + Qcache_inserts + Qcache_not_cached))*100)

Query cache use percentage = ((query_cache_size – Qcache_free_memory) / query_cache_size )*100

Average size of the queries = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache

Threads:
my.cnf:
thread_cache_size = 30

mysql> SHOW GLOBAL STATUS LIKE 'Connections';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Connections   | 91082 |
+---------------+-------+
1 row in set (0.00 sec)

mysql> SHOW GLOBAL STATUS LIKE 'Threads_created';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| Threads_created | 12    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> SHOW GLOBAL STATUS LIKE 'Max_used_connections';

+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Max_used_connections | 12    |
+----------------------+-------+
1 row in set (0.00 sec)

Attention:
Threads_created / Connections should be < 0.01 (if needed increase thread_cache_size)
thread_cache_size should be > Max_used_connections

Thread Formulas:
Thread cache hit rate = 100 – ((Threads_created / Connections) * 100)

Connection Formulas:

Percentage of used connections: processlist / MAX_CONNECTIONS

mysql> select (( pl.connections / gv.max_connections ) * 100) as percentage_used_connections from ( select count(*) as connections from information_schema.processlist ) as pl, ( select VARIABLE_VALUE as max_connections from information_schema.global_variables where variable_name = 'MAX_CONNECTIONS' ) as gv;

+-----------------------------+
| percentage_used_connections |
+-----------------------------+
|          0.6622516556291391 |
+-----------------------------+
1 row in set (0.00 sec)

Maintenance

mysql> RESET QUERY CACHE; 

will clear out the query cache

if Qcache_free_blocks approaches Qcache_total_blocks / 2, your query cache is severely fragmented.

mysql> FLUSH QUERY CACHE; 

does NOT clear out the query cache but rather defrags the cache and leaving the cached query results in place

Problem:
Qcache_lowmem_prunes value is increasing and you have a lot of Qcache_free_blocks
Reason 1:
Fragmentation is causing queries to be deleted from the cache.
In this case, increase query_cache_limit or query_cache_size, or both of them.
Reason 2:
The query cache allocates blocks with a minimum size given by the query_cache_min_res_unit system variable (default value 4096 bytes). When a query is executed, the last result block is trimmed to the actual data size so that unused memory is freed. Depending on the types of queries your server executes, you might find it helpful to tune the value of query_cache_min_res_unit:

If you have a lot of queries with small results, the default block size may lead to memory fragmentation, as indicated by a large number of free blocks. Fragmentation can force the query cache to prune (delete) queries from the cache due to lack of memory. In this case, you should decrease the value of query_cache_min_res_unit (minimum value 512 bytes). The number of free blocks and queries removed due to pruning are given by the values of the Qcache_free_blocks and Qcache_lowmem_prunes status variables.

To change in runtime

mysql> Set global query_cache_min_res_unit = 1024;

To change in my.cnf

query_cache_min_res_unit = 1024

mysql> show variables like "query%";
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| query_alloc_block_size       | 8192     |
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 1024     |
| query_cache_size             | 20971520 |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
| query_prealloc_size          | 8192     |
+------------------------------+----------+
7 rows in set (0.00 sec)