当我们查询一个数据量大、消耗时间长、数据变化不频繁、经常用同一个查询条件的时候咱们为了体改查询速度就就可以用到本期猪脚——缓存。
介绍下mysql的查询缓存,我们使用mysql语句查询的时候,每次都会重新交由mysql重新处理一次,如果我们数据更改不频繁的话,可以使用mysql自带的缓存机制,把每次的查询结果缓存起来,下次查询只需要很短的时间,甚至可以忽略不计;
那么怎么开启缓存?
我们先看一下缓存的参数:
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 | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
解释下:
have_query_cache :是否支持查询区缓存。
query_cache_limit :可缓存的查询结果集的大小。(1048576 byte/1024 =1024KB 即1MB)
query_cache_min_res_unit:每次给结果集分配内存的大小 默认是4096 byte也就是4KB
query_cache_size :表示查询缓存大小,也就是分配内存大小给查询缓存。置 set @@global.query_cache_size=100000; 这里是设置1M左右
query_cache_limit: 控制缓存查询结果的最大值
query_cache_type :缓存区状态
明白了每次参数的意思,只需要在my.nin文件中配置就可以了,资料很多,就不在这细说了。
你的数据库打开了Query Cache(简称QC)功能后,数据库在执行SELECT语句时,会将其结果放到QC中,当下一次处理同样的SELECT请求时,数据库就会从QC取得结 果,而不需要去数据表中查询。
但是缓存在一下条件下不能使用:
如果数据表被更改,那么和这个数据表相关的全部Cache全部都会无效,并删除之。这里“数据表更改”包括: INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等。举 个例子,如果数据表posts访问频繁,那么意味着它的很多数据会被QC缓存起来,但是每一次posts数据表的更新,无论更新是不是影响到了cache 的数据,都会将全部和posts表相关的cache清除。如果你的数据表更新频繁的话,那么Query Cache将会成为系统的负担。有实验表明,糟糕时,QC会降低系统13%[1]的处理能力。如果你的应用对数据库的更新很少,那么QC将会作用显著。比较典型的如博客系统,一般博客更新相对较慢,数据表相对稳定不变,这时候QC的作用会比 较明显。
接下来可以根据一下命令查看缓存的使用效果:
查看缓存命中率:
检查是否从查询缓存中受益的最简单的办法就是检查缓存命中率,当服务器收到SELECT 语句的时候,Qcache_hits 和Com_select 这两个变量会根据查询缓存的情况进行递增
查询缓存命中率的计算公式是:Qcache_hits/(Qcache_hits + Com_select)。
mysql> show status like 'qcache%';
| Variable_name | Value |
+-------------------------+-----------+
| Qcache_free_blocks | 22756 |
| Qcache_free_memory | 76764704 |
| Qcache_hits | 213028692 |
| Qcache_inserts | 208894227 |
| Qcache_lowmem_prunes | 4010916 |
| Qcache_not_cached | 13385031 |
| Qcache_queries_in_cache | 43560 |
| Qcache_total_blocks | 111212 |
MySQL查询缓存变量解释:
Qcache_free_blocks:缓存中相邻内存块的个数。数目大说明可能有碎片。FLUSH QUERY CACHE会对缓存中的碎片进行整理,从而得到一个空闲块。
Qcache_free_memory:缓存中的空闲内存。
Qcache_hits:每次查询在缓存中命中时就增大
Qcache_inserts:每次插入一个查询时就增大。命中次数除以插入次数就是不中比率。
Qcache_lowmem_prunes:缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间来看;如果这个数字在不断增长,就表示可能碎片非常严重,或者内存很少。(上面的 free_blocks和free_memory可以告诉您属于哪种情况)
Qcache_not_cached:不适合进行缓存的查询的数量,通常是由于这些查询不是 SELECT 语句或者用了now()之类的函数。
Qcache_queries_in_cache:当前缓存的查询(和响应)的数量。
Qcache_total_blocks:缓存中块的数量。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
自己的理解:
Qcache_total_blocks 所有的块,
Qcache_free_blocks 未使用的块,如果这个值比较大,就意味着内存碎片比较多了,用 flush query cache清理后 这个值应该是1或者0,因为所有的块都连在一起了。
Qcache_free_memory :缓存区还有多少内存
|Qcache_hits:缓存区的命中个数,也就是多少次是从缓存直接插的结果
Qcache_inserts 缓存区有过多少个查询结果
Qcache_lowmem_prunes 已经满出和删除的查询结果
Qcache_not_cached 没有进入缓存的查询结果
Qcache_queries_in_cache 当前有多少和查询结果集
扩展和优化
扩展:
1、当查询进行的时候,Mysql把查询结果保存在query_cache中,但是有时候要保存的结果比较大,超过了query_cahce_min_res_unit的值,这时候Mysql就会一遍检索结果,一遍慢慢保存结果,所以有时候并不是把所有的结果全部得到在一次保存,而是每次分配一块query_cahce_min_res_unit大小的内存空间保存结果集,使用完后,在接着分配一块新的,如果还不够再分配一块,以此类推,也就是说有可能在一夕查询中要进行多次的内存分配,而我们知道频繁的操作内存是要消耗时间的。
2、内存碎片产生的时候,当一块分配的内训没有完全使用,Mysql会把这块内存Trim掉,把没有使用的那部分归还以重读利用。比如,打一次分配了4KB,只用光了3KB,第2次分配了4KB,用了2KB,2次下来共剩下3KB,但是不足以在做一个内存分配单元了,这样就产生了碎片。
优化:
1、Qcache_lowmem_prunes 值比较大,说明查询缓存区设置太小
2、Qcache_free_blocks 值太大,说明碎片太多,要整理flush query cache(还有一点 flush query cache是整理查询缓存区的碎片,改善内存使用个状况
但不会清理查询缓存区的内容,这个要和RESET QUERY CACHE相区别,后者才是清除查询区缓存中的所有内容)
3.调整Query_cache_min_res_unit的大小:记住一个公式:Query_cache_min_res_unit=(query_cahce_size-qcache_free_memory)/qcacehe_aueries_in_cache。: