松散索引扫描/跳跃索引扫描
松散索引扫描Loose Index Scan是 MySQL 优化器的一种高级查询策略主要用于优化GROUP BY或DISTINCT查询。它的核心思想是不需要扫描索引中所有的行而是跳过不符合条件的行直接“跳跃”到每个分组的第一个或最后一个匹配项上。1. 核心原理从“地毯式搜索”到“跳跃式前进”在传统的**紧凑索引扫描Tight Index Scan**中数据库会扫描索引中的每一条记录。而松散索引扫描则利用了索引的有序性只读取每个组中极少数的行。直观对比假设你在一个按(A, B)排序的索引中查找每个A的最小值紧凑扫描读取A1的所有行找到最小值再读取A2的所有行……这就像翻完一整本书。松散扫描读取A1的第一行由于有序第一行必是最小值然后直接跳到索引中A2的起始位置。这就像直接看每章的目录。2. 触发松散索引扫描的条件MySQL 并不会对所有查询都使用这一策略它通常需要满足以下严格条件单表查询查询只涉及一张表。前缀索引GROUP BY或DISTINCT使用的列必须符合索引的最左前缀原则。聚合函数限制只支持MIN()和MAX()。且这些函数的参数必须是索引中的列并且紧跟在GROUP BY列之后。完整性索引中的所有列必须参与了查询要么在GROUP BY中要么在MIN/MAX中。3. 一个具体的示例假设有一张表orders索引为(customer_id, order_date)。SELECTcustomer_id,MIN(order_date)FROMordersGROUPBYcustomer_id;执行逻辑数据库定位到索引的头部。获取第一个customer_id(比如ID100) 的第一条记录。关键动作由于索引是排好序的ID100的第一条记录对应的order_date一定是该客户最早的订单。跳跃数据库直接通过索引树的 B 结构寻找比ID100大的下一个customer_id。重复此过程直到索引结束。4. 如何在 EXPLAIN 中识别当你运行EXPLAIN时如果在Extra列中看到以下字样说明松散索引扫描生效了Using index for group-by这标志着查询性能得到了质的提升因为数据库处理的数据行数从全表记录数降低到了分组数。