本文介绍云数据库 MySQL 版提供的逻辑预读功能的相关信息。
- MySQL 5.7 版本,且内核小版本为 MySQL 5.7.44_20260215 及以上。
- MySQL 8.0 版本,且内核小版本为 MySQL 8.0.43_20251215 及以上。
- MySQL 8.4 版本,且内核小版本为 MySQL 8.4.7_20260415 及以上。
MySQL 原生支持线性预读能力,根据物理位置预测需要读取的页并异步加载到 buffer pool 中,使得用户线程后续的读请求可以直接命中 buffer pool,减少用户 SQL 的 IO 时延。但在云盘场景,相邻的数据页可能在实际存储上并不连续,导致 MySQL 原生的线性预读机制对云盘版本的优化效果不佳。
云数据库 MySQL 版引入逻辑预读能力,通过用户 SQL 精准预测需要读取的页,以减少云盘版本 SQL 的 IO 时延。
逻辑预读能力通过后台线程扫描索引,根据索引精准预测用户线程需要读取的页,并异步加载到 buffer pool 中。
逻辑预读当前支持以下场景:
- 二级索引范围扫描(适用二级索引覆盖索引扫描量大的场景)
- 索引覆盖索引扫描(适用二级索引覆盖索引扫描量大的场景)
- 二级索引范围扫描回表主键(适用二级索引过滤率差的场景)
为优化 BLOB 数据的读取性能,本次迭代 MySQL 8.0 版本同步实现了 BLOB 对象的预读能力。
云数据库 MySQL 版提供了以下可修改参数,用于对逻辑预读功能进行设置。
在实际应用前,您可以通过数据库工作台手动连接到备库执行预读 SQL 以测试优化效果,避免大范围扫描对主库造成较大压力。
SET SESSION loose_enable_logical_prefetch_page=ON; # 当前连接开启逻辑预读功能
SET SESSION loose_logical_prefetch_rows_threshold=100000; # 设置预估扫描行数阈值为 100,000 行
SET SESSION loose_enable_track_index_io=ON; # 用于观察预取 IO 统计信息,存在一定开销,请避免在生产环境全局开启
select sum(k) from test.sbtest1 where (k > 1 and k < 200000); # 测试 SQL
通过 SET SESSION loose_enable_track_index_io=ON 开启 IO 指标观测后,您可以通过执行 SELECT * FROM information_schema.rds_io_trace_stats WHERE thread_id = connection_Id() 观察当前线程是否执行了逻辑预读,执行逻辑预读的详细信息,以及可能的不支持原因:
- 开启逻辑预读功能后,由于预读线程的存在,IO/CPU 资源的占用量随之增加,可能会影响同一时间内正在执行的其他 SQL 操作,因此建议仅对需要的 SQL 选择性启用逻辑预读功能。
- 逻辑预读暂不支持压缩表/分区表/非 INNODB 表。
- 逻辑预读暂不支持多值索引/虚拟生成列索引/空间索引/全文索引/向量索引。
- 由于 MySQL 5.7 版本 BLOB 数据仅能链式顺序读取,暂不支持 BLOB 对象的预读能力。
节点规格为 2C4G 的 云数据库 MySQL 版 8.0 版本的云盘实例,存储空间为 10 TB。
通过 sysbench prepare 插入 5 倍于测试范围行数的数据。
每次测试前需要重启 MySQL 进程,保证内存 buffer_pool 中没有缓存数据,以测试实际执行效率的提升比例。