Fast Query Cache

针对原生MySQL Query Cache的不足,阿里云进行重新设计和全新实现,推出Fast Query Cache,能够有效提高数据库查询性能。

前提条件

背景信息

查询缓存(Query Cache)是一种通过缓存查询结果集提升性能的机制,其核心原理是:

  • 缓存结果集:对符合条件的查询直接缓存结果,避免重复执行SQL分析、优化和执行过程,减少CPU开销。

  • 加速目标:通过降低计算资源消耗,显著提升高频简单查询的响应速度。

MySQL原生Query Cache的缺陷

MySQL原生查询缓存因设计缺陷,在高并发场景中表现欠佳,具体问题包括:

  • 并发处理较差,在多核情况下,可能并发越高性能降低越严重。

  • 内存管理较差,内存利用率低并且回收不及时,造成内存浪费。

  • 当缓存命中率较低时,性能无提升甚至会出现严重降低。

因上述问题,MySQL原生 Query Cache 在 MySQL 8.0 中被彻底移除,且在早期版本中也被默认关闭。

阿里云Fast Query Cache的创新改进

阿里云数据库团队针对原生 Query Cache 的缺陷,重新设计并实现了 Fast Query Cache,核心优化如下:

改进方向

具体措施

并发性能优化

取消全局锁,采用 无锁化设计和分片机制,实现多核并行处理,消除锁竞争。

内存管理优化

引入动态内存分配,按需分配内存,结合智能回收策略,减少碎片化并提升利用率。

缓存策略动态调优

实时监控缓存命中率与业务场景,动态调整缓存策略(如淘汰策略、缓存有效期),避免无效缓存占用资源。

写操作兼容性

通过增量失效机制,仅对受影响的查询缓存进行局部失效,降低写操作对缓存的冲击。

相比原生Query Cache,Fast Query Cache可以在不同的业务场景中放心开启,提高查询性能。

使用Fast Query Cache

您可以在RDS控制台设置参数query_cache_typequery_cache_size使用Fast Query Cache。

参数

说明

query_cache_type

Fast Query Cache功能开关,取值:

  • 0:默认值,禁用Fast Query Cache。

  • 1:使用Fast Query Cache,但可通过SQL_NO_CACHE关键字跳过缓存。

  • 2:不启用Fast Query Cache,但可通过SQL_CACHE关键字对特定语句使用缓存。

query_cache_size

Fast Query Cache使用的内存大小,取值范围:0~10485760000,需要为1024的整数倍。单位:Byte。

由于Fast Query Cache功能需要占用额外的内存空间,所以建议使用Fast Query Cache功能时同步修改参数innodb_buffer_pool_size的大小,推荐的修改步骤如下:

  1. 修改innodb_buffer_pool_size为原先的90%,分出10%的空间给query_cache_size。例如原先为{DBInstanceClassMemory*7/10},需要改为{DBInstanceClassMemory*63/100},详见调整实例Buffer Pool大小

  2. 修改参数query_cache_size,详见设置实例参数

    • 若能够评估结果集大小,query_cache_size可以设置为20% * 结果集大小

    • 若无法准确评估结果集大小,query_cache_size可以设置为10% * innodb_buffer_pool_size

    说明

    如果变更实例规格,参数query_cache_size的值不会随实例规格变化,请及时修改此参数值。

  3. 修改参数query_cache_type1,开启Fast Query Cache功能,详见设置实例参数

性能比较

在相同场景下,分别测试QC-OFF(关闭Query Cache)、MySQL-QC(开启MySQL原生Query Cache)和Fast-QC(开启Fast Query Cache)的QPS。

  • 测试环境:48 GB独享型实例

  • 测试工具:Sysbench

  • 数据量:250 MB(25张表,每张表40000条记录)

  • 场景1:全部命中(只读)

    测试场景为Sysbench oltp_point_select,用例中仅包括主键上的点查(point select),将Query Cache设为512 MB,内存大于测试数据量,缓存可以全部命中,主要关注不同并发下的性能提升效果。

    表 1. 全部命中(只读)QPS

    并发数

    QC-OFF

    MySQL-QC(相比QC-OFF提升)

    Fast-QC(相比QC-OFF提升)

    1

    8093

    8771(8.38%)

    9261(14.43%)

    8

    62262

    65686(5.50%)

    75313(20.96%)

    16

    97083

    73027(-24.78%)

    139323(43.51%)

    32

    97337

    60567(-37.78%)

    200978(106.48%)

    64

    106283

    60216(-43.34%)

    221659(108.56%)

    128

    107781

    62844(-41.69%)

    231409(114.70%)

    256

    106694

    63832(-40.17%)

    222187(108.25%)

    512

    101733

    64866(-36.24%)

    203789(100.32%)

    1024

    89548

    62291(-30.44%)

    203542(127.30%)

    全部命中

    说明

    测试结果显示,在较高并发的场景下,MySQL原生Query Cache并发处理性能出现较大幅度的降低,Fast Query Cache在各个并发场景下无性能降低,最高时能够提高一倍的QPS。

  • 场景2:高命中率(只读)

    测试场景为Sysbench oltp_read_only,用例中包含返回多条记录的范围查询,将Query Cache设为512 MB,内存才相对比较充足,命中率可以达到80%以上,这时主要关注不同并发下的性能提升效果。

    表 2. 高命中率(只读)QPS

    并发数

    QC-OFF

    MySQL-QC(相比QC-OFF提升)

    Fast-QC(相比QC-OFF提升)

    1

    5099

    6467(26.83%)

    7022(37.71%)

    8

    28782

    28651(-0.46%)

    45017(56.41%)

    16

    35333

    31099(-11.98%)

    66770(88.97%)

    32

    34864

    27610(-20.81%)

    67623(93.96%)

    64

    35503

    27518(-22.49%)

    75981(114.01%)

    128

    35744

    27733(-22.41%)

    80396(124.92%)

    256

    35685

    27738(-22.27%)

    80925(126.78%)

    512

    35308

    27398(-22.40%)

    79323(124.66%)

    1024

    34044

    26861(-22.10%)

    75742(122.48%)

    高命中率

    说明

    测试结果显示,随着并发数的增加,MySQL原生Query Cache的性能出现明显的降低,Fast Query Cache的性能则会不断提升,最高时能够提高一倍多的QPS。

  • 场景3:低命中率(只读)

    测试场景为Sysbench oltp_read_only,用例中包含返回多条记录的范围查询,将Query Cache设为16 MB,内存明显严重不足,缓存命中率只有10%左右,内存不足时会涉及缓存项的大量淘汰,影响性能,这时主要关注不同并发下的性能降低程度。

    表 3. 低命中率(只读)QPS

    并发数

    QC-OFF

    MySQL-QC(相比QC-OFF提升)

    Fast-QC(相比QC-OFF提升)

    1

    5004

    4727(-5.54%)

    5199(3.90%)

    8

    28795

    22542(-21.72%)

    28578(-0.75%)

    16

    35455

    24064(-32.13%)

    35682(0.64%)

    32

    34526

    21330(-38.22%)

    35871(3.90%)

    64

    35514

    19791(-44.27%)

    36051(1.51%)

    128

    35983

    19519(-45.75%)

    36253(0.75%)

    256

    35695

    19168(-46.30%)

    36337(1.80%)

    512

    35182

    18420(-47.64%)

    35972(2.25%)

    1024

    33915

    20168(-40.53%)

    34546(1.86%)

    低命中率

    说明

    测试结果显示,MySQL原生Query Cache的性能降低明显,最多出现了接近50%的性能损失,Fast Query Cache优化了低命中率场景,几乎不会带来任何额外的性能损失。

  • 场景4:读写混合

    测试场景为Sysbench oltp_read_write,每个事务中都有对表的更新操作,可以认为缓存基本处于失效状态,频繁的更新操作涉及缓存的主动淘汰,理论上会比较影响性能,这时主要关注不同并发下的性能衰减程度。

    表 4. 读写混合QPS

    并发数

    QC-OFF

    Fast-QC(相比QC-OFF提升)

    1

    4152

    4098(-1.30%)

    8

    21359

    21195(-0.77%)

    16

    26020

    25548(-1.81%)

    32

    27595

    26996(-2.17%)

    64

    29229

    28733(-1.70%)

    128

    29265

    28828(-1.49%)

    256

    29911

    29616(-0.99%)

    512

    29148

    28816(-1.14%)

    1024

    29204

    28824(-1.30%)

    读写混合

    说明

    测试结果显示,Fast Query Cache在读写混合场景下不会出现过多的性能降低,整体性能影响很小。

实践指南

适用场景

Fast Query Cache主要用于提升读密集型场景的性能,建议读多写少场景开启:

  • 业务以查询为主,写操作频率较低(如电商商品详情页、报表查询)。

  • 对指定表使用SQL_CACHE 显式开启缓存(如读写比高的表)。您也可以通过TABLE_STATISTICS表查看表级别的读写比,对读写比高的表通过SQL_CACHE关键字显式开启Fast Query Cache。查询TABLE_STATISTICS表请参见Performance Insight

不建议开启场景:

  • 写多读少场景(如高频交易系统):缓存频繁失效,可能引发性能下降。

  • 数据实时性要求高(如股票行情):缓存数据可能与实时数据不一致。

  • 在全局开启前建议查看InnoDB Buffer Pool的命中率(命中率 = 1 - Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests),如果命中率低于80%,则不建议开启。

缓存使用方式(query_cache_type

query_cache_type参数支持会话级修改,用户可以根据真实业务场景进行灵活设置,请参见以下建议:

参数值

说明

适用场景

0

全局禁用Fast Query Cache

写多读少场景或缓存命中率极低的场景

1

全局开启,自动缓存所有符合条件的查询

读多写少、数据更新频率低的场景

2

仅对显式添加SQL_CACHE的查询开启缓存

数据量大、访问模式不稳定或需精细化控制的场景

缓存大小(query_cache_size)设置

query_cache_sizeSQL息息相关,如果缓存中有返回多条记录的查询,缓存可能需要是数据量的数倍。如果SQL中不包含范围查询,可以参见以下测试来评估数据量和query_cache_size的关系。

  • 测试环境:48 GB独享型实例(innodb_buffer_pool_size = 6 GB)

  • 测试工具:Sysbench

  • 数据量:10 GB(100张表,每张表400000条记录)

测试场景为Sysbench oltp_point_select、64并发、Special分布(20%热点)。测试不同query_cache_size大小对于性能的影响。对应上述的数据量,全量结果集的真实大小为2.5 GB。

表 5. 不同缓存QPS

query_cache_size(MB)

QC-OFF

Fast-QC命中率

Fast-QC(相比QC-OFF提升)

64

98236

22%

99440(1.23%)

128

98236

45%

114155(16.21%)

256

98236

72%

140668(43.19%)

512

98236

82%

151260(53.98%)

1024

98236

84%

153866(56.63%)

2048

98236

87%

159597(62.46%)

4096

98236

92%

169412(72.45%)

Fast Query Cache在不同query_cache_size的设置下都不会引起性能退化,对于主键查询操作,在不同缓存命中率下都有性能提升,达到90%以上时,提升效果比较明显;对于范围查询或带Order By的排序语句,缓存命中率低于90%时,也能节约大量的CPU,带来较大的性能提升。