官方文档说明:MySQL :: MySQL 8.0: Retiring Support for the Query Cache
MySQL查询缓存是查询结果缓存。它将以SEL开头的查询与哈希表进行比较,如果匹配,则返回上一次查询的结果。
进行匹配时,查询必须逐字节匹配,例如 SELECT * FROM t1; 不等于select * from t1;此外,一些不确定的查询结果无法被缓存,任何对表的修改都会导致这些表的所有缓存无效。
8.0撤销查询缓存
MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。
你可以看到,如果查询命中缓存,MySQL 不需要执行后面的复杂操作,就可以直接返回结果,这个效率会很高。
但是大多数情况下建议不要使用查询缓存,为什么呢?因为查询缓存往往弊大于利。
- 查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。
- 对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。
- 比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。
最佳案例
正如我几年前在个人博客上写的:
查询缓存的理想使用场景往往在很大程度上是只读的,这个场景下,通过非常大的代价去检查数百万行数据,但是指返回很少的结果 一个假设出的例子是可能有一个复杂的查询来得到一个网页上的表单中的下拉列表的值,在这种情况下,查询缓存可以掩盖由于缺少的索引引起的查询性能问题,这对新手用户有帮助。
因此,适用于查询缓存的最理想的方案是只读,特别是需要检查数百万行后仅返回数行的复杂查询。如果你的查询符合这样一个特点,开启查询缓存会提升你的查询性能。
随着技术的进步,经过时间的考验,MySQL的工程团队发现启用缓存的好处并不多。
主要原因
首先,查询缓存的效果取决于缓存的命中率,只有命中缓存的查询效果才能有改善,因此无法预测其性能。
其次,查询缓存的另一个大问题是它受到单个互斥锁的保护。在具有多个内核的服务器上,大量查询会导致大量的互斥锁争用。
通过基准测试发现,大多数工作负载最好禁用查询缓存(5.6的默认设置):query_cache_type = 0
如果你认为会从查询缓存中获得好处,请按照实际情况进行测试。
- 数据写的越多,好处越少
- 缓冲池中容纳的数据越多,好处越少
- 查询越复杂,扫描范围越大,则越受益