MySQL设置查询缓存的用意:把查询到的结果缓存起来,下次再执行相同查询时就可以直接从结果集中取;这样就比重新查一遍要快的多。
查询缓存的最终结果是事与愿违:之所以查询缓存并没有能起到提升性能的做用,客观上有如下两点原因。
1、把SQL语句的hash值作为键,SQL语句的结果集作为值;这样就引起了一个问题如 select user from mysql.user 和 SELECT user FROM mysql.user 这两个将会被当成不同的SQL语句,这个时候就算结果集已经有了,但是一然用不到。
2、当查询所基于的低层表有改动时与这个表有关的查询缓存都会作废、如果对于并发度比较大的系统这个开销是可观的;对于作废结果集这个操作也是要用并发访问控制的,就是说也会有锁。并发大的时候就会有Waiting for query cache lock 产生。
3、至于用不用还是要看业务模型的。
一、如何配置查询缓存
query_cache_type 这个系统变量控制着查询缓存功能的开启的关闭。
query_cache_type参数用于控制缓存的类型,注意这个值不能随便设置,必须设置为数字,可选项目以及说明如下:
如果设置为0,那么可以说,你的缓存根本就没有用,相当于禁用了。但是这种情况下query_cache_size设置的大小系统是否要为其分配呢,这个问题有待于测试。
如果设置为1,将会缓存所有的结果,除非你的select语句使用SQL_NO_CACHE禁用了查询缓存。
如果设置为2,则只缓存在select语句中通过SQL_CACHE指定需要缓存的查询。
这个参数的设置有点奇怪:
1、如果事先查询缓存是关闭的然而用 set @@global.query_cache_type=1; 会报错ERROR 1651 (HY000): Query cache is disabled; restart the server with query_cache_type=1 to enable it
2、如果事先是打开着的尝试去闭关它,那么这个关闭也是不完全的,这种情况下查询还是会去尝试查找缓存。最好的关闭查询缓存的办法就是把my.cnf 中的query_cache_type=0然后再重启mysql。
二、查询缓存相关的系统变量
登录mysql执行指令:show variables like '%query_cache%';
have_query_cache 表示这个mysql版本是否支持查询缓存。
query_cache_limit 表示单个结果集所被允许缓存的最大值。
query_cache_min_res_unit 每个被缓存的结果集要占用的最小内存。
query_cache_size 用于查询缓存的内存大小。
query_cache_type 用于控制查询缓存功能的开关与类型
query_cache_size=0是默认配置,其注释意思是说,MYSQL的查询缓存用于缓存select查询结果,并在下次接收到同样的查询请求时,不再执行实际查询处理而直接返回结果,有这样的查询缓存能提高查询的速度,使查询性能得到优化,前提条件是你有大量的相同或相似的查询,而很少改变表里的数据,否则没有必要使用此功能。可以通过Qcache_lowmem_prunes变量的值来检查是否当前的值满足你目前系统的负载。注意:如果你查询的表更新比较频繁,而且很少有相同的查询,最好不要使用查询缓存。
具体配置方法:
1.将query_cache_size设置为具体的大小,具体大小是多少取决于查询的实际情况,但最好设置为1024的倍数,参考值32M。
2.增加一行:query_cache_type=1
配置完后的部分文件如下:
query_cache_size=128M
query_cache_type=1
保存文件,重新启动MYSQL服务
三、如何监控查询缓存的命中率
Qcache_free_memory 查询缓存目前剩余空间大小。
Qcache_hits 查询缓存的命中次数。
Qcache_inserts 查询缓存插入的次数。
也就是说缓存的命中率为 Qcache_hits/(Qcache_hits+Qcache_inserts)
四、遇到的问题
在JAVA应用项目中遇到过数据库查询不到结果的现象,试试关闭数据库缓存,将query_cache_type置为0。