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

前提条件

PolarDB集群版本需为PolarDB MySQL 8.0且Revision version为8.0.1.1.5或以上,您可以参见查询版本号确认集群版本

问题与优化

查询缓存(Query Cache)是为了提高查询性能而实现的一种缓存策略,其基本思想是:对于每个符合条件的查询语句,直接对结果集进行缓存,当下次查询命中时,直接从缓存中取出对应的结果集返回,不需要经历SQL的分析、优化、执行等复杂过程,通过节约CPU资源来达到查询加速的目标,是一项非常实用的技术。

MySQL原生Query Cache在设计和实现上存在着较多严重问题:

  • 并发处理较差,在多核情况下,可能并发越高性能降低越严重。
  • 内存管理较差,内存利用率低且回收不及时,造成内存浪费。
  • 当缓存命中率较低时,性能无提升甚至严重降低。

由于以上问题,MySQL原生Query Cache没有得到广泛应用,在最新版的MySQL 8.0中,取消此功能。PolarDB对Query Cache进行重新设计和全新实现,进行了如下优化:

  • 优化并发控制

    取消全局锁同步机制,采用无锁机制,重新设计并发场景下的同步问题,能够充分利用多核的处理能力,保证高并发场景下的性能。

  • 优化内存管理

    取消内存预分配机制,采用更加灵活的动态内存分配机制,及时回收无效的内存,保证内存的真实利用率。

  • 优化缓存机制

    动态检测缓存利用率,实时调整缓存策略,解决命中率偏低或读写混合等场景下的性能降低问题。

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

开启Fast Query Cache

PolarDB已经为不同的集群规格配置了不同的Fast Query Cache内存空间。您仅需要调整loose_query_cache_type参数即可开启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、Case6、Case7等场景中,使用了Fast Query Cache后的缓存命中率范围在63%~99%之间,最大QPS提升范围在53%~106%之间。Fast Query Cache的内存利用率很高,Case7在大数据量的point select场景中,其命中率依然达到了99%,性能提升较明显。同时在低命中率场景中,Fast Query Cache对并发性能的影响很小,基本在3%以内。对于高并发读写混合场景,性能影响也在2%以内。

    说明 本文测试场景中的所有测试数据仅针对测试集群中的主节点。
    • Case1:25 x 40k (tables x rows),rand-type = special oltp_read_only1
    • Case2:25 x 40k (tables x rows),rand-type = uniform oltp_read_only2
    • Case3:25 x 40k (tables x rows),rand-type = special oltp_point_select3
    • Case4:25 x 40k (tables x rows),rand-type = uniform oltp_point_select4
    • Case5:25 x 400k (tables x rows),rand-type = special oltp_read_only5
    • Case6:25 x 400k (tables x rows),rand-type = uniform oltp_read_only6
    • Case7:25 x 400k (tables x rows),rand-type = special oltp_point_select7
    • Case8:25 x 400k (tables x rows),rand-type = uniform oltp_point_select8
    • Case9:25 x 400k (tables x rows), rand-type = special oltp_read_write9

实践指南

  • 适用场景指南
    • 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小时。