0
点赞
收藏
分享

微信扫一扫

为什么MySQL 8.0删除了查询缓存

微言记 2022-11-08 阅读 127

前言

MySQL在其最新的8.0版本中,删除了查询缓存(Query Cache)区域,就此,MySQL的Query Cache彻底的退出了历史舞台。在5.7版本中,MySQL已经将Query Cache的选项(query_cache_type)的缺省值设为了关闭,并在5.7.20版本中,将该配置标记为了Deprecated

那么MySQL经历这么多个版本的迭代后,为什么会取消该区域?Query Cache设计的初衷是什么?

本篇,让我们来一起了解MySQL Query Cache

什么是MySQL Query Cache

以上是MySQL官方文档中对于Query Cache的定义,MySQL查询缓存是MySQL中比较独特的一个缓存区域,用来缓存特定Query的整个结果集信息,且共享给所有客户端。

为了提高完全相同的Query语句的响应速度,MySQL 会对查询语句进行hash计算后,把得到的hash值与Query查询的结果集对应存放在Query Cache中。

当开启Query Cache之后,MySQL 会对接收到的每一个SELECT语句通过特定的hash算法计算该Queryhash值,然后通过该hash值到Query Cache中去匹配。

如果通过hash值匹配到了一样的Query,则直接将cache中相应的Query结果集返回给客户端。

由于Query Cache是针对SELECT语句的hash值作为key值进行存储的,意味着SQL语句哪怕出现一个字符的不同,缓存也无法进行命中。

对于5.7.20版本之前,可以通过编辑my.cnf配置,通过如下参数开启Query Cache

...
[mysqld]
query_cache_type=1
query_cache_size=10M
query_cache_limit=256K

各个参数含义如下:

参数含义取值范围
query_cache_type查询缓存类型0:关闭缓存
1:缓存全部请求,仅当语句中包含SELECT SQL_NO_CACHE时放弃缓存
2:对指定的请求进行缓存,仅当语句中包含SELECT SQL_CACHE时进行缓存
默认关闭
query_cache_size查询缓存区大小默认大小1M,该值必须为1024的整数倍,如果不是整数倍,MySQL 会自动调整降低最小量以达到1024的倍数
query_cache_limit缓存结果集大小限制,允许 Cache 的单条 Query 结果集的最大容量,如果超过该值,则不会缓存结果集默认大小1MB

Query Cache的优势

Query Cache设计之初,MySQL希望可以利用查询缓存,提升查询的效率,在执行每一次SELECT的时候,MySQL都会首先经过Query Cache区域,检查查询是否可以命中缓存,如果命中,则直接返回结果集,相较于从硬盘(Disk)检索数据,直接从内存(RAM)中获取数据集无疑是极为高效的,可以大大的节省查询执行的时间。

如果业务场景是只读不写的情况,且有大量重复的查询请求,开启Query Cache会带来巨大的性能提升,这意味着每一次查询请求,会有很大的概率直接命中缓存,而无需经过SQL解析优化,硬盘加载数据等一系列过程。

Query Cache的劣势

1、查询SQL的命中

Query Cache中对SQL语句的缓存,是基于字节级别的(The query must match byte-for-byte ),这意味着SQL语句发生任何一点变化,Query Cache都无法进行命中,这对于实际生产环境的查询,显得有些过于苛刻。

2、缓存过期

Query Cache的淘汰策略过于苛刻,任何对于表中数据的修改,都会使得缓存失效,这里的修改包括:INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE,这个特性意味着,只有对于读远大于写的数据表,Query Cache才能发挥作用,对于读写均衡以及写多读少的场景,Query Cache基本上很难发挥作用。

3、分区表禁用

如果数据表使用了分区,Query Cache将会被自动的禁用,无法生效。

4、增加额外的负载

当开启Query Cache选项后,如果查询请求没有命中Query Cache时,MySQL会需要额外的性能开销去处理结果集,写入Query Cache中,最糟糕的情况下,这个额外的性能开销是13%,但实际场景中的情况会更加的复杂,通常情况下,额外的性能开销会低于该值,但这仍是一笔无谓的性能损耗。

总上,我们会发现,Query Cache好像非常的鸡肋,因为在我们大多数的场景中,很少情况下会出现只读不写的情况,更多的情况则是读多写少或读写均衡,这使得Query Cache很难对我们的实际业务产生正向的影响。

MySQL官方的抉择

经过上述对Query Cache的优缺点的了解,我们可以明白Query Cache适合于什么样的业务场景,但对于大多数场景下,Query Cache是比较鸡肋的,因此,从MySQL 5.6版本开始,将Query Cache设置为了默认关闭,并在MySQL 8.0版本中,彻底移除了Query Cache,并给出了解释:

A Top-Down Approach to Achieving Performance Predictability in Database Systems

MySQL官方团队对于在8.0版本中彻底移除Query Cache的决策做出了如上的解释,并给出了所替代的解决方案建议——使用第三方工具客户端缓存ProxySQL 来代替Query Cache

如下图所示,MySQL官方给出了使用ProxySQL 对比原生Query Cache 性能报告,从图中可以清晰的看到,ProxySQL 的查询性能完胜原生的Query Cache

performance improvement when moving the cache to the client

对于ProxySQL的使用,在这里将不会过多的介绍,在后面的篇幅中,我们会详细聊一聊ProxySQL,如果您对ProxySQL感兴趣,可以参考其官方文档:

https://proxysql.com/documentation/query-cache/

本篇参考:

MySQL 8.0: Retiring Support for the Query Cache:

https://dev.mysql.com/blog-archive/mysql-8-0-retiring-support-for-the-query-cache/

The MySQL Query Cache:

https://dev.mysql.com/doc/refman/5.7/en/query-cache.html

How To Optimize MySQL with Query Cache on Ubuntu 18.04:

https://www.digitalocean.com/community/tutorials/how-to-optimize-mysql-with-query-cache-on-ubuntu-18-04

举报

相关推荐

0 条评论