🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[![mysql-query-cache-seems-so-beautiful](http://imysql.com/wp-content/uploads/2015/03/mysql-query-cache-seems-so-beautiful.png)](https://box.kancloud.cn/2015-07-29_55b878aba787b.png) _备注:插图来自淘宝苏普的博客并保留水印,如果觉得不当还请及时告知 :)_ 写在前面:MySQL的query cache大部分情况下其实只是鸡肋而已,建议全面禁用。当然了,或许在你的场景下还是挺好的,还能发挥作用,那就继续使用吧,把本文当做参考就好。 不过,可能有的人人为只需要把 query_cache_size 大小调整为 0 就可以了,可以忽略 query_cache_type 参数的值,反正它也是可以在线调整的。 事实果真如此吗?让我们来实际模拟测试下就知道了。 我们模拟了以下几种场景: ~~~ 1、初始化时,同时设置 query_cache_size 和 query_cache_type 的值为 0; 2、初始化时,设置 query_cache_size = 0,但设置 query_cache_type = 1; 3、初始化时,设置 query_cache_size = 0,query_cache_type = 1,但是启动后立刻 修改 query_cache_type = 0 4、初始化时,设置 query_cache_size = 0,query_cache_type = 0,但是启动后立刻 修改 query_cache_type = 1 5、初始化时,设置 query_cache_size = xMB,query_cache_type = 1,但是启动后立刻 修改 query_cache_type = 0 ~~~ 经过测试,可以得到下面几个重要结论(详细测试过程请见最后): ~~~ 1、想要彻底关闭query cache,务必在一开始就设置 query_cache_type = 0,即便是启动后将 query_cache_type 从 1 改成 0,也不行; 2、即便query_cache_size = 0,但 query_cache_type 非 0 的话,在实际环境中,可能会频繁发生 Waiting for query cache lock; 3、一开始就设置 query_cache_type = 0 的话,没有办法在运行 过程中再次动态启用,反过来则可以。也就是说,一开始是启用 query cache 的, 在运行过程中将其关闭,但事实上仍然会发生  Waiting for query cache lock,并没有真正的关闭; ~~~ 关于query cache的延伸阅读,请见: 1、我的前同事waterbin帅哥的悲惨经历:[MySQL Troubleshoting:Waiting on query cache mutex](http://blog.csdn.net/dba_waterbin/article/details/9201645 "MySQL Troubleshoting:Waiting on query cache mut") 2、淘宝苏普的旧文:[Query Cache,看上去很美](http://www.orczhou.com/index.php/2009/08/query-cache-1/ "Query Cache,看上去很美") 详细测试过程: 一、测试方法 采用sysbench模拟并发oltp请求: ~~~ sysbench --test=tests/db/oltp.lua --oltp_tables_count=10 --oltp-table-size=100000 --rand-init=on --num-threads=64 --oltp-read-only=off --report-interval=10 --rand-type=uniform --max-time=1800 --max-requests=0 run ~~~ 二、具体几种测试模式 1、一直关闭QC(query cache的简写,下同),即  query_cache_size = 0, query_cache_type = 0 测试过程中,一直都没有和query cache lock相关的状态出现,结果tps:2295.34 2、启用QC,但QC size 设置为 0,即:query_cache_size = 0,query_cache_type = 1 测试过程中,一直有 Waiting for query cache lock 状态出现,结果tps:2272.52 3、启用QC,但QC size为0,但启动时立刻关闭QC,即初始化时 query_cache_size = 0,query_cache_type = 1,启动后立刻修改 query_cache_type = 0 测试过程中,也一直有 Waiting for query cache lock 状态出现,结果tps:2311.54 4、关闭QC,但启动后立刻启用QC,即初始化时 query_cache_size = 0,query_cache_type = 0,启动后立刻修改 query_cache_type = 1 这时,会提示报错信息: 失败:ERROR 1651 (HY000): Query cache is disabled; restart the server with query_cache_type=1 to enable it 也就是说,如果一开始就关闭 QC 的话,是没办法在运行过程中动态再启用QC的。 5、启用QC,并设置QC size为256M,即 query_cache_size = 256M,query_cache_type = 1 这种情况下,在测试过程中一直有 Waiting for query cache lock 状态出现,并且结果tps也很差,只有 1395.39(几个案例中最差的一种) 6、启用QC,设置QC size为256M,但启动后立刻关闭QC,即 query_cache_size = 256M,query_cache_type = 1,启动后立刻修改 query_cache_type = 0 这种情况下,在测试过程中也一直有  Waiting for query cache lock 状态出现,结果tps:2295.79(在这个模式下,如果设置 query_cache_type = 2,效果也不佳) 第三种模式下,虽然看起来tps还不错,但毕竟上面只是简单模拟测试,实际情况下如果有频繁的query cache lock的话,tps肯定不会太好看。 因此,总的来说,想要获得较高tps的话,最好还是一开始就关闭QC,不要心存侥幸或者固守陈规。