对于一个MySQL的sql语句的执行流程,大致可以分为如下几个阶段:

发起请求->连接层-> 缓存层->语法分析层->优化层->执行层->存储引擎层。

其中,缓存层用于记录历史查询的缓存结果,方便下一次的查询时,直接 查询缓存 返回结果。

从 MySQL 8.0 开始,查询缓存 功能被完全废弃,这是 MySQL 开发团队基于优化性能和架构设计趋势做出的关键决策。

下面我们详细分析 MySQL 8.0 废弃查询缓存的原因。


1. 查询缓存简介

查询缓存(Query Cache)是 MySQL 在早期版本中的一个功能,用于存储已执行的 SELECT 查询结果,以及查询结果的关联性。在满足以下条件时,如果应用相同的查询,MySQL 可以直接从缓存中返回结果,而无需再次读取磁盘或计算结果:

  • 查询是完全相同的(包括语句、参数,以及 SQL 格式化的空格和换行等)。

  • 表的内容未发生变化(即表中数据未被修改)。

这曾为一些场景带来了性能提升,但也引发了一些性能和扩展性的问题。


2. 查询缓存的主要问题

虽然查询缓存在一定条件下能够提升性能,但它在现代高并发场景中存在一些非常明显的缺点,主要问题如下:

2.1 高并发环境下性能开销巨大

  • 缓存失效频繁:
    查询缓存依赖表数据的一致性。如果表的数据发生了变化(如 INSERTUPDATEDELETE),与该表相关的所有查询缓存都会失效并需要被清除。这在频繁写入的场景中(如实时更新系统)造成了过度的缓存失效,从而影响性能。

  • 全局互斥锁的问题:
    查询缓存是通过一个全局锁(Mutex)来管理的。在高并发场景下,多个线程需要访问和更新查询缓存,而查询缓存的锁机制会导致严重的争用,即:

  • 每次有表数据变化,所有相关缓存和操作都需要获取锁,影响性能。

  • 在并发负载较高的情况下,查询缓存的锁甚至引发整个系统性能下降。

2.2 动态数据场景适应性差

查询缓存非常适合不常更新的数据(如静态网页或报表查询结果),但现代应用通常需要处理动态、实时更新的数据,这会导致查询缓存快速失效,从而难以发挥其性能优势。

2.3 缓存命中率极低

查询缓存仅支持完全等价的 SQL 语句(包括空格、大小写等),这使得缓存命中率在实际应用中非常低:

  • 即使两个查询逻辑上是完全相同的,但由于语句格式化或参数稍有差别,也无法利用缓存。

  • 这种严格匹配的规则降低了缓存的可用性。

对于缓存需求,越来越多的开发者选择借助外部缓存方案(如 RedisMemcached),这些方案提供了灵活的缓存管理,能够显著提升命中率。

2.4 更优秀的替代方案

MySQL 引入了多种新的优化特性,逐渐替代了查询缓存的功能:

  • InnoDB Buffer Pool:
    替代作用部分查询缓存,通过对磁盘数据页的缓存,可以加速数据读取。

  • 外部缓存解决方案:
    开发者通常在应用层结合 Redis 或 Memcached 实现查询结果缓存,其灵活性和性能明显高于 MySQL 内置的查询缓存。


3. MySQL 官方解决方案及思路

MySQL 8.0 团队在废弃查询缓存功能时,建议开发者在数据库设计和应用层优化中考虑以下替代方案:

3.1 使用 InnoDB Buffer Pool

MySQL 提供了强大的 InnoDB Buffer Pool,用于缓存数据页(包括表数据和索引),可以显著减少从磁盘读取数据的次数。相比查询缓存,Buffer Pool 的灵活性更高,而且性能稳定。

  • 开发者可以通过调整参数 innodb_buffer_pool_size 控制缓存大小,以适应业务需求。

3.2 应用层缓存优化

很多现代应用已经开始使用 Redis、Memcached 等外部缓存系统来存储 SQL 查询结果。这些缓存方案:

  • 支持复杂的缓存策略(比如部分失效、基于时间的过期策略)。

  • 提供了分布式缓存功能,可以充分利用服务器资源。

  • 灵活性远高于查询缓存,应用开发者可以根据实际业务设计自定义规则。


4. 废弃缓存层对性能的影响

废弃查询缓存对 MySQL 的性能是积极的,尤其是以下两点:

  1. 高并发时性能提升:
    去除查询缓存的全局锁意味着减少了锁开销,高并发场景的性能瓶颈得以缓解。

  2. 查询和写入操作效率提升:
    不再因为查询缓存失效频率过高而导致额外的开销,查询和写入操作能更直接地通过优化的存储引擎和 Buffer Pool 完成。


5. 总结

MySQL 8.0 废弃查询缓存的原因可以归纳为以下几点:

  1. 查询缓存在高并发场景下存在严重的性能瓶颈(例如全局锁争用)。

  2. 动态数据场景导致缓存频繁失效,命中率较低,难以提升整体性能。

  3. 应用层缓存方案(如 Redis)更灵活且性能更强,逐步替代了 MySQL 查询缓存。

  4. MySQL 内部已经有优秀的替代方案(如 InnoDB Buffer Pool),无需再额外维护查询缓存功能。

通过废弃查询缓存,MySQL 8.0 能更专注于优化基础数据库的性能和扩展性,例如对存储引擎(InnoDB)等的改进,整体上提供了更稳定、更高效的数据库体验。如果需要类似缓存的功能,推荐使用应用层的缓存方案或者调整 Buffer Pool 配置来达到效果。