MySQL Query Cache

MySQL Query Cache实现原理

MySQL的Query Cache实现原理实际上并不是特别复杂,简单来说就是将客户端请求的Query语句(仅限于SELECT类型的Query)通过一定的hash算法进行一个计算,得到一个hash值,存放在一个hash桶中

同时将该Query的结果集(ResultSet)也存放在一个内存Cache中。存放Query hash值的链表中每一个hash值所在节点的同时,还存放了该Query所对应的Result Set的Cache所在的内存地址,以及该Query涉及的所有Table的标识等一些其他相关信息

系统接受到任何一个SELECT类型的Query时,首先计算出其hash值,然后通过该hash值到Query Cache中去匹配,如果找到了完全相同的Query,则直接将之前所缓存(cache)的Result Set返回给客户端,完全不须要进行后面的任何步骤即可完成这次请求

而后端的任何一个表的任何一条数据发生变化之后,也会通知Query Cache,须要将所有与该Table有关的Query的Cache全部失效,并释放出之前占用的内存地址,以便后面其他的Query能够使用。

QC不适用于下面几个场景

1、子查询或者外层查询;
2、存储过程、存储函数、触发器、event中调用的SQL,或者引用到这些结果的;
3、包含一些特殊函数时,例如:BENCHMARK()、CURDATE()、CURRENT_TIMESTAMP()、NOW()、RAND()、UUID()等等;
4、读取mysql、INFORMATION_SCHEMA、performance_schema 库数据的;
5、类似SELECT…LOCK IN SHARE MODE、SELECT…FOR UPDATE、SELECT..INTO OUTFILE/DUMPFILE、SELECT..WHRE…IS NULL等语句;
6、SELECT执行计划用到临时表(TEMPORARY TABLE);
7、未引用任何表的查询,例如 SELECT 1+1 这种;
8、产生了 warnings 的查询;
9、SELECT语句里加了 SQL_NO_CACHE 关键字;
 
如何关闭QC?
query_cache_type = off
query_cache_size = 0
 
 
查看query cache相关的状态变量
mysql> show global status like 'QCache%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| Qcache_free_blocks      | 1       |
| Qcache_free_memory      | 1031368 |
| Qcache_hits             | 0       |
| Qcache_inserts          | 0       |
| Qcache_lowmem_prunes    | 0       |
| Qcache_not_cached       | 83      |
| Qcache_queries_in_cache | 0       |
| Qcache_total_blocks     | 1       |
+-------------------------+---------+
 
 
 
Qcache_free_blocks 表示query cache中目前还有多杀剩余的blocks,如果该值显示较大,则说明query cache中的内存碎片较多,需要进行整理了;
Qcache_free_memory 表示query cache目前剩余的内存大小;
Qcache_hits 表示query cache有多少次命中;
Qcache_inserts 表示未命中cache后将结果集再写入到cache中的次数;
Qcache_lowmem_prunes 表示多少条query因为内存不足而被清除出query_cache;
Qcache_not_cached 表示因为query_cache_type的设置或者不能被cache的query的数量;
Qcache_queries_in_cache 表示当前cache的query的数量;
Qcache_total_blocks 当前query cache中的block数量。
 
查询缓存命中率 ≈ (Qcache_hits – Qcache_inserts) / Qcache_hits * 100%
 
 
 
查看query cache的系统变量
 
mysql> show variables like '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 0       |
| query_cache_type             | OFF     |
| query_cache_wlock_invalidate | OFF     |
+------------------------------+---------+
 
 
have_query_cache 表示是否支持query cache;
query_cache_limit 表示query cache存放的单条query最大结果集,默认值为1M,结果集大小超过该值的query不会被cache;
query_cache_min_res_unit 表示query cache 每个结果集存放的最小内存大小,默认4k;
query_cache_size 表示系统中用于query cache的内存大小;
query_cache_type 系统是否打开了query cache功能;
query_cache_wlock_invalidate 针对myisam存储引擎,设置当有write lock在某个table上面的时候,读请求是要等待write lock释放资源之后再查询还是允许直接从query cache中读取结果,默认是OFF,可以直接从query cache中取得结果。
原文地址:https://www.cnblogs.com/l10n/p/12606210.html