mysql8 loose index skip scan 特性加速分组查询性能

前言

要理解Loose Index Scan(松散索引扫描) 如何加速 GROUP BY,核心是抓住「索引有序性 」和「跳过无效数据、只取分组核心值」这两个关键点------它彻底避开了"遍历所有数据→临时表分组"的低效路径,直接从有序索引中"精准提取"分组结果。

先看「常规 GROUP BY」的低效逻辑(对比更易理解)

假设表 t1 有索引 idx(c1,c2),数据如下(索引是有序存储的,所以实际索引中 c1 的值是连续的):

c1 c2
1 10
1 20
2 30
2 40
3 50

如果执行 SELECT c1, MIN(c2) FROM t1 GROUP BY c1;常规方式的执行步骤是:

  1. 扫描全表(或全索引),读取所有 5 行数据;
  2. 创建临时表,把 c1=1 的两行、c1=2 的两行、c1=3 的一行分别归集;
  3. 对每个分组计算 MIN(c2)
  4. 返回结果。

这个过程要遍历所有数据,还需要临时表,数据量越大效率越低。

再看「Loose Index Scan」的加速逻辑

因为索引 idx(c1,c2)有序的 (BTREE 索引特性),c1 相同的记录在索引中是连续排列的。Loose Index Scan 利用这一点,只读取每个分组的"关键值",跳过同分组的其他数据

步骤拆解(还是上面的查询 SELECT c1, MIN(c2) FROM t1 GROUP BY c1;):

  1. 定位索引中第一个 c1=1 的记录,其 c2=10------因为索引有序,同组后续的 c1=1 记录的 c2 一定≥10,所以 MIN(c2) 直接确定为 10,无需读取 c1=1 的下一条记录(c2=20)
  2. 跳过所有 c1=1 的剩余记录,直接定位到第一个 c1=2 的记录,其 c2=30------同理,MIN(c2)=30,跳过 c1=2 的下一条记录(c2=40);
  3. 跳过所有 c1=2 的剩余记录,定位到第一个 c1=3 的记录,其 c2=50------MIN(c2)=50
  4. 直接返回结果,全程只读取了 3 条记录(每个分组 1 条),且无需创建临时表

核心加速点总结:

维度 常规 GROUP BY Loose Index Scan
数据读取量 遍历所有符合条件的记录 仅读取每个分组的"首条关键记录"
临时表 必须创建(归集分组) 无需创建
计算逻辑 先归集所有数据,再算聚合 直接从索引首条记录推导聚合结果
时间复杂度 O(N)(N 为总记录数) O(M)(M 为分组数,M << N)

再举一个带范围条件的例子,更显"松散"的优势

如果查询是 SELECT c1, MIN(c2) FROM t1 WHERE c1 < 3 GROUP BY c1;

  • 常规方式:读取 c1<3 的所有 4 条记录(c1=1 的 2 条 + c1=2 的 2 条),临时表分组后计算;
  • Loose Index Scan:仅读取 c1=1 的第一条、c1=2 的第一条,共 2 条记录,直接得出结果,跳过了同组的其他 2 条记录。

为什么叫"松散"?

"松散"的核心是------它不"紧密"遍历索引的每一个键值,而是跳过同分组的所有冗余记录,只抓每个分组的"锚点"(首条记录),就像从有序的数组中"跳着找"分组,而非逐个遍历。

关键前提:为什么能"跳着找"?

必须满足「GROUP BY 列是索引最左前缀」+「聚合函数仅 MIN/MAX 且列紧跟分组列」,本质是:

  1. 索引有序性保证了"同分组的记录连续",所以首条记录就能确定 MIN/MAX;
  2. 索引最左前缀保证了"分组列在索引中是最优先的排序维度",能直接按分组列跳着定位。

如果不满足这些条件(比如用 SUM、GROUP BY 列不是最左前缀),就无法"跳着找",只能退化为 Tight Index Scan 或常规方式。

简单总结:Loose Index Scan 把 GROUP BY 的执行成本,从「依赖数据总量」降到了「依赖分组数量」,分组数远小于数据量时,加速效果极其显著。

官方文档

https://dev.mysql.com/doc/refman/8.0/en/group-by-optimization.html

相关推荐
哈哈不让取名字21 分钟前
用Pygame开发你的第一个小游戏
jvm·数据库·python
程序员敲代码吗21 分钟前
Python异步编程入门:Asyncio库的使用
jvm·数据库·python
liux352826 分钟前
MySQL主从复制技术全面解析:从基础原理到高级架构实践(八)
mysql
a程序小傲30 分钟前
听说前端又死了?
开发语言·前端·mysql·算法·postgresql·深度优先
志凌海纳SmartX32 分钟前
榫卯企业云平台:让企业自建云更简单
数据库
老邓计算机毕设36 分钟前
SSM学生信息管理系统ow05a(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·学生信息管理系统·ssm 框架·高校教育管理
小Mie不吃饭1 小时前
MySQL慢查询日志全解析:从配置到优化实践
mysql
Access开发易登软件2 小时前
数据处理中的两大基石:何时选择Excel,何时考虑Access
数据库·信息可视化·excel·vba·access
Alex老夫子2 小时前
android room数据库增加字段注意事项
android·数据库