mysql的查询缓存
Query Cache查询缓存:
原理:
hash结果会区分大小写
- 请求时会先在查询缓存中找一遍,如果没有,则交给解释器执行,再交给查询优化器根据相关算法、索引选择最优查询方法,再给对应的存储引擎查询数据,返回结果给请求者,并把结果hash计算后,缓存下来
缓存的优缺点:
- 提高查询性能
- 不支持大小写,规则判断不够智能,影响效率
- 使用的是内存空间,不能持久化保存
不会缓存的情况:
- 查询语句中加了 sql_no_cache 参数
- 查询语句中含有获得值的函数,包含:自定义函数,如:now() ,curdate()、get_lock()、rand()、convert_tz() 等
- 对系统数据库的查询:mysql、information_schema 查询语句中使用SESSION级别变量或存储过程中的局部变量
- 查询语句中使用了 lock in share mode、for update的语句,查询语句中类似SELECT …
- into 导出数据的语句
- 对临时表的查询操作
- 存在警告信息的查询语句
- 不涉及任何表或视图的查询语句
- 某用户只有列级别权限的查询语句
- 事务隔离级别为Serializable时,所有查询语句都不能缓存
SELECT语句的缓存控制:
- SQL_CACHE:显式指定存储查询结果于缓存之中,开启缓存功能后,默认使用
- SQL_NO_CACHE:显式查询结果不予缓存,开启缓存后只对系统库默认使用,其他手动指定
注: SELECT语句才会缓存,其它均不会缓存,且系统库默认一律不会缓存
查询缓存相关的服务变量:
query_cache_min_res_unit | 内存最小分配单元,默认4K(相当于磁盘块),较小值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来浪费,会导致碎片过多,内存不足 |
query_cache_limit | 单个查询结果能缓存的最大值,单位字节,默认为1M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CACHE |
query_cache_size | 查询缓存总共可用的内存空间;单位字节,最小值40KB,低于此值有警报。必须按字节计算 |
query_cache_wlock_invalidate | 表在被其他会话锁定时,是否可以用缓存的结果返回,默认off开启 |
query_cache_type | 是否开启缓存功能,取值为ON, OFF, demand(按需开启)。开启时SELECT的结果符合缓存条件即会缓存,否则,不予缓存,显式指定SQL_NO_CACHE,不予缓存,此为默认值。为DEMAND或2时,查询缓存功能按需进行,显式指定SQL_CACHE才会缓存 |
查询缓存相关的状态变量:
show global status like 'Qcache%'; 查看状态变量
显示信息 | 含义 |
---|---|
Qcache_free_blocks | 处于空闲状态 Query Cache中内存 Block 数 |
Qcache_total_blocks | 缓存中总Block ,当Qcache_free_blocks相对此值较大时,可能用内存碎片,执行FLUSH QUERY CACHE清理碎片 |
Qcache_free_memory | 未使用的缓存内存总量 |
Qcache_hits | 缓存命中次数 |
Qcache_inserts | 向缓存中插入新数据的次数,即未命中的次数 |
Qcache_lowmem_prunes | 记录因为内存不足而被移除出查询缓存的查询数 |
Qcache_not_cached | 没有被缓存的sql数,以及由于query_cache_type设置的不会被缓存的sql |
Qcache_queries_in_cache | 缓存中的sql总数 |
例:查询缓存的使用
set query_cache_type=1; #开启缓存
show global status like 'Qcache%'; #查询缓存的状态
select * from t1;
#再次查看缓存状态,发现已经缓存了一条记录,且新插入了一条缓存
show global status like 'Qcache%';
缓存优化:
优化逻辑:
- 大部分未缓存-->query_cache_limit大小检查。不够则增加
- 是否有很多验证工作-->检查缓存碎片,调小:query_cache_min_res_units
- 是否有很多验证工作(分配内存地址耗时等)-->检查缓存空间大小,小了会频繁交替,小了就增大
- 是否有很多验证工作(分配内存地址耗时等)-->检查sql是否有很多更新语句,由则是正常现象,没有则检查其他配置
- 缓存功能是否启动,修改配置文件
缓存参数相关的数值计算:
内存最小分配单位:
(缓存空间总大小-剩余空间)/缓存的总数
(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
缓存命中率 :
命中次数/(命中次数+未命中次数)*100%
Qcache_hits / ( Qcache_hits + Qcache_inserts ) * 100%
缓存内存利用率:
(缓存空间总大小-剩余空间)/缓存空间总大小*100%
query_cache_size – qcache_free_memory) / query_cache_size * 100%