Fork me on GitHub

【性能测试】MYSQL缓存命中率03

一、查询缓存(query cache) 

缓存命中率:所有的查询语句,命中缓存的请求数,占所有请求数的比例

查看是否开启缓存命中率
# 缓存的开关
show variables like '%query_cache_type%';
# 缓存的大小
show variables like '%query_cache_size%';

开启缓存设置
MySQL的配置文件my.ini或my.cnf中:
1. query_cache_size : 设置为具体的大小
2. 增加一行:query_cache_type=1
query_cache_type:
设置为0,OFF,缓存禁用
设置为1,ON,缓存所有的结果
缓存大小

查看缓存相关选项
show global status like 'QCache%';

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_hits – Qcache_inserts) / Qcache_hits * 100% 
 
我们再查询一下服务器关于query_cache的配置:
show variables like 'query_cache%';

 各字段的解释:
  query_cache_limit:超过此大小的查询将不缓存
  query_cache_min_res_unit:缓存块的最小大小
  query_cache_size:查询缓存大小
  query_cache_type:缓存类型,决定缓存什么样的查询,示例中表示不缓存 select sql_no_cache 查询 
  query_cache_wlock_invalidate:当有其他客户端正在对MyISAM表进行写操作时,如果查询在query cache中,是否返回cache结果还是等写操作完成再读表获取结果。
  query_cache_min_res_unit的配置是一柄”双刃剑”,默认是4KB,设置值大对大数据查询有好处,但如果你的查询都是小数据查询,就容易造成内存碎片和浪费。

查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%
  如果查询缓存碎片率超过20%,可以用FLUSH QUERY CACHE整理缓存碎片,或者试试减小query_cache_min_res_unit,如果你的查询都是小数据量的话。
  查询缓存利用率 = (query_cache_size - Qcache_free_memory) / query_cache_size * 100%
  查询缓存利用率在25%以下的话说明query_cache_size设置的过大,可适当减小;查询缓存利用率在80%以上而且Qcache_lowmem_prunes > 50的话说明query_cache_size可能有点小,要不就是碎片太多。 
  示例服务器 查询缓存碎片率 = 0.0005%,查询缓存利用率 = 0.4428%,查询缓存命中率 = 94.5%

结论:这个示例服务器的缓存碎片率很低,并且查询缓存命中率很高,但查询缓存利用率相对较低,建议适当增加缓存大小以提高利用率。

其他可能存在的分析思路:

1、缓存失败情况

1)缓存碎片、内存不足、数据修改都会造缓存失败。如果配置了足够的缓存空间,而且query_cache_min_res_unit的大小也设置的合理。那么缓存失效应该主要是数据修改导致的。可以通过Qcache_lowmen_prunes参数来查看有多少次失效是由于内存不足导致的。

2)当某个表正在写入数据,则这个表的缓存(命中缓存,缓存写入等)将会处于失效状态

3)在Innodb中,如果某个事务修改了这张表,则这个表的缓存在事务提交前都会处于失效状态,在这个事务提交前,这个表的相关查询都无法被缓存。

2、减少缓存碎片

1)设置合适的query_cache_min_res_unit值

我们在分析缓存参的时候知道,MySQL并不是一下子分配query_cache_size内存作为缓存,而是将内存分为若干个query_cache_min_res_unit小内存,即使本次缓存没有达到一个缓存块大小也需要占用一个缓存块大小。但query_cache_min_res_unit也不能设置太小,设置太小会造成MySQL不断的分配很多个内存块来缓存本次SQL语句的结果集。

2)使用 FLUSH QUERY CACHE 命令整理缓存碎片

使用 FLUSH QUERY CACHE 命令可以有效的整理缓存碎片,来释放碎片占用的空间,但需要注意的是这个命令在整理缓存期间,会导致其他连接无法使用查询缓存。

  

备注:

https://www.cnblogs.com/adamans/articles/13141498.html

https://www.cnblogs.com/qxfan/p/7026293.html

https://www.cnblogs.com/ttaylor/p/15853073.html

  

 
posted @ 2024-02-14 22:04  橘子偏爱橙子  阅读(394)  评论(0编辑  收藏  举报