松散索引扫描/跳跃索引扫描

松散索引扫描(Loose Index Scan) 是 MySQL 优化器的一种高级查询策略,主要用于优化 GROUP BY 或 DISTINCT 查询。

它的核心思想是:不需要扫描索引中所有的行,而是跳过不符合条件的行,直接"跳跃"到每个分组的第一个或最后一个匹配项上。


1. 核心原理:从"地毯式搜索"到"跳跃式前进"

在传统的**紧凑索引扫描(Tight Index Scan)**中,数据库会扫描索引中的每一条记录。而松散索引扫描则利用了索引的有序性,只读取每个组中极少数的行。

直观对比:

假设你在一个按 (A, B) 排序的索引中查找每个 A 的最小值:

  • 紧凑扫描 :读取 A=1 的所有行找到最小值,再读取 A=2 的所有行......这就像翻完一整本书。
  • 松散扫描 :读取 A=1 的第一行(由于有序,第一行必是最小值),然后直接跳到 索引中 A=2 的起始位置。这就像直接看每章的目录。

2. 触发松散索引扫描的条件

MySQL 并不会对所有查询都使用这一策略,它通常需要满足以下严格条件:

  1. 单表查询:查询只涉及一张表。
  2. 前缀索引 :GROUP BY 或 DISTINCT 使用的列必须符合索引的最左前缀原则。
  3. 聚合函数限制 :只支持 MIN() 和 MAX()。且这些函数的参数必须是索引中的列,并且紧跟在 GROUP BY 列之后。
  4. 完整性 :索引中的所有列必须参与了查询(要么在 GROUP BY 中,要么在 MIN/MAX 中)。

3. 一个具体的示例

假设有一张表 orders,索引为 (customer_id, order_date)。

sql 复制代码
SELECT customer_id, MIN(order_date)
FROM orders
GROUP BY customer_id;

执行逻辑:

  1. 数据库定位到索引的头部。
  2. 获取第一个 customer_id (比如 ID=100) 的第一条记录。
  3. 关键动作 :由于索引是排好序的,ID=100 的第一条记录对应的 order_date 一定是该客户最早的订单。
  4. 跳跃 :数据库直接通过索引树的 B+ 结构,寻找比 ID=100 大的下一个 customer_id。
  5. 重复此过程,直到索引结束。

4. 如何在 EXPLAIN 中识别?

当你运行 EXPLAIN 时,如果在 Extra 列中看到以下字样,说明松散索引扫描生效了:

Using index for group-by

这标志着查询性能得到了质的提升,因为数据库处理的数据行数从 全表记录数 降低到了 分组数。


相关推荐
龙腾AI白云6 小时前
AI检索增强生成(RAG):解决大模型幻觉的核心落地技术
数据库·人工智能·机器学习·知识图谱
一 乐6 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
zzj_2626106 小时前
MySQL常用操作
数据库·mysql
其实防守也摸鱼6 小时前
Fastjson 反序列化漏洞(JNDI注入)
android·数据库·安全·oracle·自动化·fastjson·反序列化
haerapi7 小时前
把 PostgreSQL 复制巡检做成可审计闭环:确定性采集、阈值判定与受控模型归纳
数据库·postgresql
yolo_guo7 小时前
调试mysql延迟与libevent回调实际发送回复时机问题
c++·mysql·libevent
旺仔学长 哈哈7 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
微学AI8 小时前
不让每一步都调用最贵模型:用蓝耘智能路由改造自主式研究 Agent
数据库·人工智能·蓝耘
yjb.gz8 小时前
Oracle19 RAC查看集群状态及磁盘空间情况(巡检)
数据库
钝挫力PROGRAMER8 小时前
开发踩坑记:MyBatis selectKey、空 SQL
数据库·sql·mybatis