MySQL query cache mechanism []

About MySQL query cache

After opening the query cache, the query resolution process:
before parsing a query, if the query cache is turned on, then MySQL will give priority to check whether the query query data cache hit. If the current query happens to hit the query cache, MySQL checks a user permission before returning query results. If permission is not a problem, MySQL will skip all other phases (parsing, optimization, execution, etc.), to get the results directly from the cache and returned to the client. In this case, the query will not be resolved without execution plan, will not be executed.

When the open Query Cache MySQL Server, MySQL Server will each SELECT statement received Hash value calculated by the Query specified Hash algorithm, then the values ​​hashi to match to the Query Cache.

  • If there is no match, this hash value is stored in a hash list, and the Query result set is stored into the cache, each node is stored hash value list hashi Quey stored result sets corresponding address in the cache, and the query It relates to some of the table information;
  • If a match to the same hash value by Query, directly corresponding to the cache Query result set returned to the client.

Currently MySQL Query Cache will cache select statements, other similar show, use the statement is not cache MySQL Query Cache are based on each SQL text as the key to store, before applying Query Cache, SQL text will not do any deal with. In other words, two SQL statements, as long as the difference of even one character (for example, the case is not the same, one more space, and more comments), then the two SQL Cache will use a different address. Such as: The following three SQL will be stored in three different caches, although their results are the same. * the FROM people WHERE name SELECT = 'surfchen'; SELECT * WHERE people the FROM / Hey ~ / name = 'surfchen'; the FROM people the SELECT * WHERE name = 'surfchen';

MySQL caching mechanism

MySQL caching simply means caching query results sql text and, if you run the same SQL, server to get the results directly from the cache, without the need to go to parse and execute SQL. If the table is changed, then use the table of all cached queries will no longer be valid, queries the value of the relevant entry in the cache is emptied. Change herein refers to any data structure or table changes, including INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE DROP DATABASE, or the like, including those changes to the query table mapping table using MERGE. Obviously, this is frequently updated for table, query cache is not suitable, but for some infrequently changing data table and there is a lot of the same SQL query, the query cache will save a great performance.

Queries must be exactly the same (byte for byte the same) it can be considered the same. In addition, the same query string for other reasons may be considered to be different. Use different databases, different protocol versions, or different default character sets are considered different queries and queries are cached.

Cache Rules

Opened the cache, MySQL Server will automatically query and returns the result set into memory, and then check the next time taken directly from memory;

Result Cache is shared by the sessions, so a client cache query results, you can use another client;

MySQL Query Cache content select set of results, cache use the full SQL string as key, and is case sensitive, spaces, and so on. That is, two SQL must be exactly the same would lead to cache hits. That is to check the query cache, MySQL Server to SQL will not do any treatment, it is precisely the use of client inquiries coming from, as long as the character case or comment a little bit different, the query cache is considered to be a different query;

prepared statement never cache the results, even if exactly the same parameters. After 5.1 will be improved.

where conditions as a function contains no uncertain will never be cache, such as current_date, now and so on.

Functions such date if the return is based on the level of hours or days, it is best to work out re-transmission inside.

Will not be much of a result set cache (<query_cache_limit)

MySQL database cache in the sub-sub-table environment does not work

There are trigger the implementation of SQL, custom function, MySQL also cache does not work

Manually clear the cache

Manually clear the cache can use the following three SQL:

  • FLUSH QUERY CACHE; # clean up the query cache memory fragmentation
  • RESET QUERY CACHE; # remove all queries from the query cache
  • FLUSH TABLES; # close all open table, and this operation will clear the query cache
Cache memory management mechanism

MySQL Query Cache memory pool using the technology, to manage memory allocation and release, rather than through the operating system. The basic unit of memory pool is used by the variable-length block, used to store information type, size, data and the like; a result set by the cache block string together these lists. the minimum block length is query_cache_min_res_unit.

When the server is started, it will initialize the memory cache is needed is a complete free block. When the need to cache query results, starting with a free block in the application data block space parameters query_cache_min_res_unit configuration, even if a small cached data, application data block is this, because the query returns a result when he began to allocate space, not at this time predict how much results.

Allocate blocks of memory space you need to lock the block, so the operation is slow, MySQL will try to avoid this operation, select the memory blocks as small as possible, if not, continue to apply, if there is spare when storing the complete release of excess.

However, if concurrent operation, the need to recycle the remaining space is very small, less than the query_cache_min_res_unit, can not be used again, will produce fragments.

Not active

If a large cache cache misses, but in fact the vast majority of queries are cached on the server, then you must have the following occurs:

  • The query cache is not yet complete warm-up, that is, MySQL has no chance to query results are cached.
  • Before the query has never been executed. If the application does not repeat execute a query, even if the warm-up is completed there will still be a lot of cache misses.
  • Cache invalidation operations too much, cache fragmentation, lack of memory, data modification will cause a cache miss. * Modify the data can be viewed via parameter Com_ circumstances (including Com_update, Com_delete, etc.), you can also see how many times by Qcache_lowmem_prunes failure is caused due to insufficient memory.

When writing data to a table, the table must be all of the cache is set to fail, if the cache space is large, consumption will be great, may make the system dead for some time, because this operation is by global lock operation to protection.

InnoDB tables, when you modify a table, set the cache invalidation, but multiple versions of these characteristics will temporarily modify other matters shield, before the transaction commits, all queries can not use the cache until the transaction is committed, so long time of the transaction, will greatly reduce the query cache hits.

MySQL Query Cache debris optimization

Here Insert Picture Description

MySQL Query Cache advantages and disadvantages

Advantages:
Query Cache Query took place in MySQL receiving a query request from a client, before SQL parsing and query after query to verify permissions. After That, after receiving the MySQL client query SQL, just only need to be appropriate permissions verification, will be to find results Query Cache, you do not even need to be analyzed to optimize the implementation of the plan after Optimizer module, and more any interaction storage engine does not need to occur. Because Query Cache is memory-based, returned directly from memory corresponding results, thus reducing the amount of disk I / O and CPU computing, resulting in very high efficiency.

Disadvantages:

hash and hash calculation query Find resources to bring consumption. If query_cache_type set to 1 (ie ON), then MySQL will each received SELECT type queries hash calculation, and then look for the cache results of this query exists. Although hash calculations and lookup efficiency is high enough, a query arising from the overhead can be ignored, but when it comes to high concurrency, there are thousands of queries, hash calculations and lookup brought overhead It must be taken seriously.

Query Cache failure problem. If you change the table more frequently, will result in Query Cache failure rate is very high. Not only refers to the change table data table changes, further comprising a table structure, or any change in the index.

Different query, but the query same query results are cached, and this will result in excessive consumption of memory resources. Query the character case, different spaces or comments, Query Cache will be considered different queries (because their hash values are different).
Related system variable is set unreasonable will cause a lot of memory fragmentation, and this will lead to frequent clean up Query Cache memory.

Set to use the query cache way

Use query_cache_type variable to open the query cache, open in three ways:

ON: normal cache. It said in a query using the SELECT statement, if not specified SQL_NO_CACHE or other non-deterministic function, usually cached query results.

DEMAND: Specifies the SQL_CACHE only cache. Said in a SELECT statement using a query, you must specify SQL_CACHE only in the SELECT statement cache the query results down the SELECT statement:

select SQL_CACHE name from user where id = 15; #只有明确指定 SQL_CACHE 的SELECT语句,才会将查询结果缓存。

OFF: The query cache.

Effective immediately, restart the service failure
mysql> set global query_cache_type=1;

When the my.cnf, query_cache_type = OFF, after the start mysql service, use the above statement to open the query cache in mysql command line, you will get an error:

ERROR 1651 (HY000): Query cache is disabled; restart the server with query_cache_type=1 to enable it

In such cases, the query cache is not open in the mysql command line, you must modify the my.cnf query_cache_type = ON, and then restart the mysql service.

Permanent

Modify my.cnf:

query_cache_type = ON

Restart mysql service

Set the query cache size
query_cache_size :查询缓存的总体可用空间。

If query_cache_size = 0, that even if you set query_cache_type = ON, the query cache is still unable to work.

Effective immediately, restart the service failure

mysql> set global query_cache_size=536870912;   #单位为字节,必须为1024的倍数。

Permanent
modification my.cnf:

query_cache_size = 500M   #支持单位:K,M,G
Query cache related parameters

Server variables associated with caching functions:

mysql> SHOW GLOBAL VARIABLES LIKE '%query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| have_query_cache             | YES     |      
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

Variable Description:

have_query_cache: whether the MySQL Server supports Query Cache.

query_cache_limit: MySQL can cache maximum results; the size of a query if the result is greater than this value, it will not be cached;

query_cache_min_res_unit: Query minimum block size (in bytes) of the cache allocation. The default value is 4096 (4KB). When the query, MySQL to save the query result in the query cache, but if you want to save the result of relatively large, more than the value of query_cache_min_res_unit, this time mysql to the side of search results, while the results saved, so, sometimes not to All results obtained after one-time all saved, but a query_cache_min_res_unit each allocation of memory space to save the result set, after use, followed by a redistribution of such a block, if not enough, then a redistribution block, by such a push, that is to say, it is possible in a query, mysql to operate multiple memory allocation. Appropriate regulatory query_cache_min_res_unit can optimize your memory if the query results are some small result, the default query_cache_min_res_unit can cause large amounts of memory fragmentation if your results are some of the larger resule, you can put the proper tone query_cache_min_res_unit

Calculating an average single query cache size: (query_cache_size-Qcache_free_memory) / Qcache_queries_in_cache

query_cache_size: Query total available buffer space in bytes; it must be a multiple of 1024;

query_cache_strip_comments: After removing the comment section to control whether the SQL query statement in the query cache is stored as a key.

query_cache_type: Type query cache; cache function is turned on, turned in three ways {ON | OFF | DEMAND};

query_cache_wlock_invalidate: If a table is locked, whether to return data in the cache, off by default, it is also recommended. Typically, when a client WRITE lock on a MyISAM table, if the query result in the query cache, the other client is not locked, you can query the table. This variable is set to 1, you can WRITE lock on the table, so that all queries to the table in the query cache is invalidated. So that when the lock is in effect, can force other clients attempt to access the table to wait for the end.

State variables associated with the cache
mysql> SHOW  GLOBAL STATUS  LIKE  'Qcache%';
+-------------------------+----------+
| Variable_name            | Value   |
+-------------------------+----------+
| Qcache_free_blocks       | 1       | #查询缓存中的空闲块
| Qcache_free_memory       | 16759656| #查询缓存中尚未使用的空闲内存空间
| Qcache_hits              | 16      | #缓存命中次数
| Qcache_inserts           | 71      | #向查询缓存中添加缓存记录的条数
| Qcache_lowmem_prunes     | 0       | #表示因缓存满了而不得不清理部分缓存以存储新的缓存,这样操作的次数。若此数值过大,则表示缓存空间太小了。
| Qcache_not_cached        | 57      | #没能被缓存的次数
| Qcache_queries_in_cache  | 0       | #此时仍留在查询缓存的缓存个数
| Qcache_total_blocks      | 1       | #共分配出去的块数
+-------------------------+----------+
Calculate the cache hit rate
mysql> SHOW GLOBAL STATUS WHERE Variable_name='Qcache_hits' OR Variable_name='Com_select';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Com_select    | 279292490 | #非缓存查询次数
| Qcache_hits   | 307366973 | # 缓存命中次数
+---------------+-----------

Cache hit rate: Qcache_hits / (Qcache_hits + Com_select)

"Hit and write" ratio
mysql> SHOW GLOBAL STATUS WHERE Variable_name='Qcache_hits' OR Variable_name='Qcache_inserts';
+----------------+-----------+
| Variable_name  | Value     |
+----------------+-----------+
| Qcache_hits | 307416113    | #缓存命中次数
| Qcache_inserts | 108873957 | #向查询缓存中添加缓存记录的条数
+----------------+-----------+

The ratio of "hits and is written" in: Qcache_hits / Qcache_inserts # If this ratio is greater than 3: 1, indicating that the buffer is valid; if it exceeds 10: 1, is quite satisfactory;

Published 210 original articles · won praise 14 · views 50000 +

Guess you like

Origin blog.csdn.net/LU_ZHAO/article/details/105035546