针对MySQL原生Query Cache的不足,PolarDB进行重新设计和全新实现,推出了Fast Query Cache,能够有效提高数据库查询性能。
使用限制
- PolarDB MySQL版8.0版本且Revision version为8.0.1.1.5或以上;
- PolarDB MySQL版5.7版本且Revision version为5.7.1.0.15或以上;
- PolarDB MySQL版5.6版本且Revision version为5.6.1.0.29或以上。
问题与优化
查询缓存(Query Cache)是为了提高查询性能而实现的一种缓存策略,它通过节约CPU资源来达到查询加速的目标,是一项非常实用的技术。其基本思想是:对于每个符合条件的查询语句,直接对结果集进行缓存。当该结果集被再次查询命中时,直接从缓存中读取对应的结果集并返回,不需要经历SQL的分析、优化、执行等复杂的过程。
MySQL原生Query Cache在设计和实现上存在较多的严重问题,具体如下:
- 并发处理较差,在多核情况下,并发度越高性能降低可能越严重。
- 内存管理较差,内存利用率低且回收不及时,造成内存浪费。
- 当缓存命中率较低时,性能无提升甚至严重降低。
基于以上问题,MySQL原生Query Cache没有得到广泛应用,在最新版的MySQL 8.0中,取消了此功能。PolarDB对Query Cache进行重新设计和全新实现,进行了如下优化:
- 优化并发控制
取消全局锁同步机制,采用无锁机制,重新设计并发场景下的同步问题,能够充分利用多核的处理能力,保证高并发场景下的性能。
- 优化内存管理
取消内存预分配机制,采用更加灵活的动态内存分配机制,及时回收无效的内存,保证内存的真实利用率。
- 优化缓存机制
动态检测缓存利用率,实时调整缓存策略,解决命中率偏低或读写混合等场景下的性能降低问题。
相比MySQL原生Query Cache,您可以在不同的业务场景中开启Fast Query Cache以提高查询性能。
开启Fast Query Cache
- 对于PolarDB MySQL版8.0版本,loose_query_cache_type参数设置为
ON
后,即可开启Fast Query Cache功能。 - 对于PolarDB MySQL版5.6或者5.7版本,query_cache_type参数设置为
1
后,即可开启Fast Query Cache功能。
性能比较
在相同场景下,分别测试QC-OFF(关闭Query Cache)和PolarDB-QC(开启Fast Query Cache)的QPS。
- 测试环境
- 一个规格为8核64 GB的PolarDB MySQL版8.0集群版。
- Query Cache内存为4 GB。
- 测试工具
Sysbench
- 测试数据量
- 25张表,每张表4万条记录。
- 25张表,每张表40万条记录。
- 测试用例
使用以下Sysbench内置用例,分别在rand-type=special和uniform条件下进行测试。
- oltp_read_only
- oltp_point_select
- oltp_read_write
- 测试结果及说明
从以下测试中可以看到,Fast Query Cache在高并发场景较高命中率下性能提升非常明显。在Case1、Case3、Case4、Case5、Case7等场景中,使用了Fast Query Cache后的缓存命中率范围在63%~99%之间,最大QPS提升范围在53%~106%之间。Fast Query Cache的内存利用率很高,Case7在大数据量的point select场景中,其命中率依然达到了99%,性能提升较明显。同时在低命中率场景下,Case2和Case6中的Fast Query Cache对并发性能的影响很小,基本在3%以内。对于高并发读写混合场景,性能影响也在2%以内。
说明 本文测试场景中的所有测试数据仅针对测试集群中的主节点。- Case1:25 x 40k (tables x rows),rand-type = special oltp_read_only
- Case2:25 x 40k (tables x rows),rand-type = uniform oltp_read_only
- Case3:25 x 40k (tables x rows),rand-type = special oltp_point_select
- Case4:25 x 40k (tables x rows),rand-type = uniform oltp_point_select
- Case5:25 x 400k (tables x rows),rand-type = special oltp_read_only
- Case6:25 x 400k (tables x rows),rand-type = uniform oltp_read_only
- Case7:25 x 400k (tables x rows),rand-type = special oltp_point_select
- Case8:25 x 400k (tables x rows),rand-type = uniform oltp_point_select
- Case9:25 x 400k (tables x rows), rand-type = special oltp_read_write
- Case1:25 x 40k (tables x rows),rand-type = special oltp_read_only
实践指南
- 适用场景指南
- Fast Query Cache主要作用是提高读操作性能,建议在读多写少的场景下开启,或者使用SQL_CACHE关键字针对读多写少的表开启。如果写多读少,数据的更新非常频繁,查询性能可能会降低2%左右。
- Fast Query Cache内存利用率很高,适用于更新很少但访问量很大的点查场景中,大幅提升并发访问性能。
- 缓存使用方式(loose_query_cache_type)
Fast Query Cache完全兼容原生Query Cache的使用方法,可通过loose_query_cache_type参数控制缓存。
参数名 取值 说明 loose_query_cache_type OFF(默认值) 禁用Fast Query Cache。 ON 默认在查询中使用Fast Query Cache功能,但可通过SQL_NO_CACHE关键字跳过缓存。 DEMAND 默认在查询中不使用Fast Query Cache功能,但可通过SQL_CACHE关键字对特定语句使用缓存。 说明loose_query_cache_type参数支持会话级修改,您可以参考如下建议并根据真实业务场景进行灵活设置:
- 对于更新频繁、写多读少等不适合Query Cache的场景,应将loose_query_cache_type全局设置为OFF。
- 对于较多重复查询、缓存命中率较高或者较多重复的慢查询场景,可以将loose_query_cache_type全局设置为ON。
- 对于仅存在少量重复查询的场景,可以将loose_query_cache_type设置为DEMAND,仅对指定的语句,通过SQL_CACHE关键字使用Fast Query Cache。
- 缓存租约时间 (query_cache_lease_time)
Fast Query Cache会动态回收查询缓存的内存,降低内存的使用量。对于未失效的查询缓存,若在query_cache_lease_time时间(单位为秒)内没有被任何查询命中,则会在超过缓存租约时间后被释放,所对应的内存将被回收。该参数默认值为3600秒,即1小时。