本文介绍云数据库 MySQL 版提供的分页查询性能优化功能的相关信息。
在社区版 MySQL 的实现里,limit 和 offset 是在 SQL 层完成处理的。对于以下查询,存储引擎会至少返回 10000010 行,随后在 SQL 层将返回的第 10000001 至 10000010 行数据作为结果返回。
SELECT * FROM sbtest1 LIMIT 10000000, 10;
limit 和 offset 通常会在分页场景中一同使用。在分页场景,尤其是深分页场景(即 offset 跳过的行数远多于 limit 保留的行数)下,过滤被 offset 跳过的行的速度对查询的整体性能有显著影响。
云数据库 MySQL 版针对此场景进行了优化,将 limit 和 offset 直接下推至存储引擎。一方面,这能够显著减少存储引擎与 SQL 层之间的交互;另一方面,若存储引擎通过二级索引扫描数据,在将 limit 和 offset 下推之后,还能够大幅减少回表次数。
MySQL 8.0 版本,且内核小版本为 MySQL 8.0.32_20250415 及以上。
说明
您可通过查看实例信息查看实例的内核小版本。如您的实例为 MySQL 8.0.32_20250415 之前的版本,可手动升级实例内核小版本。
修改 loose_limit_offset_pushdown_threshold 参数的运行值为非 -1 的值,即可开启分页查询性能优化特性。
名称 | 默认值 | 是否需要重启以生效 | 取值范围 | 级别 | 参数描述 |
---|---|---|---|---|---|
loose_limit_offset_pushdown_threshold | -1 | 否 | [-1, 9223372036854775807] | Global、Session | 用于设置 offset 行数不小于多少时,启用分页查询性能优化功能。设置为 -1 表示任何时候都关闭分页查询性能优化功能。 |
示例 1:简单的 limit + offset 查询。
SELECT * FROM sbtest1 LIMIT 10000000, 10;
示例 2:包含 where 条件的 limit + offset 查询,要求 where 条件能够完全下推。
SELECT * FROM sbtest1 WHERE id > 10 AND id < 60000000 LIMIT 10000000, 10;
示例 3:包含 order by 的 limit + offset 查询,要求存在 order by 列相关的索引,且查询计划中使用了该索引。
-- 存在 k 上的 secondary index SELECT * FROM sbtest1 ORDER BY k LIMIT 10000000, 10;
可以通过 EXPLAIN 语句查看一个 SQL 是否会进行分页查询性能优化。
EXPLAIN SELECT c_int FROM lop_test ORDER BY c_int LIMIT 5, 5;
上述语句可以进行优化,输出如下(Using pushed limit offset 表示进行了分页查询性能优化):
测试环境为 MySQL 8.0 版本,实例规格为独享型 4C16G,创建 20000000 行的 sysbench 表,开启该特性前后分别执行上述的示例 1~3,执行耗时如下: