SQL Server 不支持索引跳跃扫描(Index Skip Scan),其索引使用严格遵循最左前缀原则,即WHERE条件必须包含联合索引的首列才能触发Index Seek;若缺失首列(如索引为(category, status, type)但查询只用status = 'done' AND type = 'refund'),则只能回退至Index Scan或Table Scan,无法自动拆解遍历首列distinct值——该机制仅存在于MySQL 8.0.13+和Oracle,SQL Server至今(2026年6月)仍无此能力。

SQL Server 没有索引跳跃扫描(Index Skip Scan)这个特性。
SQL Server 根本不支持 Index Skip Scan
这是最容易踩的坑:把 MySQL 8.0+ 或 Oracle 的优化机制,误套到 SQL Server 上。SQL Server 的查询优化器从不自动拆解查询、遍历索引首列所有 distinct 值来“补全最左前缀”。它的索引使用严格遵循最左前缀原则——WHERE 条件没带上联合索引第一个字段,该索引就无法用于 seek,只能回退到 scan 或其他可用索引。
- MySQL 8.0.13+ 的
INDEX SKIP SCAN是通过内部重写查询(如UNION ALL多个带首列值的子查询)实现的 - Oracle 也有同名特性,行为类似
- SQL Server 至今(2026 年 6 月最新版 2022 CU22)仍无此能力,官方文档和执行计划中均无对应提示项(如
Index Skip Scan或类似Loose Index Scan)
SQL Server 加速 GROUP BY 的真实路径是索引覆盖 + 排序利用
SQL Server 要让 GROUP BY 快,靠的是让聚合能直接走索引顺序,避免排序和临时表。关键不是“跳过”,而是“对齐”:
- 索引必须以
GROUP BY字段为前导列,例如CREATE INDEX IX_user_id_amount ON orders(user_id, amount),才能支持SELECT user_id, SUM(amount) FROM orders GROUP BY user_id - 如果还有
ORDER BY user_id,且索引已按该顺序存储,就能省掉额外排序步骤 - 若聚合函数是
MIN()/MAX()且字段在索引中紧随分组列之后(如(user_id, created_at)),SQL Server 可能利用索引有序性直接取首/尾值,但这是 Tight Index Scan 的变体,不是 Skip Scan - 执行计划里看到
Stream Aggregate且上层是Index Seek或Index Scan(非Table Scan),说明走对了路;若出现Hash Aggregate或Sort + Stream Aggregate,基本意味着索引没对上或数据无序
误以为 SQL Server 有 Skip Scan 时的典型错误现象
当你在 SQL Server 上写了类似 WHERE status = 'done' AND type = 'refund',而索引是 (category, status, type),却期待它能跳过 category 直接生效——结果只会触发 Index Scan 或更糟的 Table Scan,执行计划里 Actual Rows 和 Estimated Rows 差距巨大,CPU 和 I/O 都飙升。
- 检查方法:运行
SET STATISTICS XML ON,看<RelOp>节点里是否出现IndexScan且Predicate包含大量status = ... AND type = ...,而不是SeekPredicates - 修复方式不是等“跳跃”,而是重建索引:把高频过滤字段提到前面,比如
(status, type, category),或加单独的(status, type)索引 - 注意:SQL Server 不会因
category的 distinct 值少(比如只有 3 个)就自动启用某种“跳跃逻辑”——这点和 MySQL 的loose index scan或index skip scan完全不同
真正要盯住的,永远是执行计划里的 type、key、rows 和 Extra(虽然 SQL Server 不叫 Extra,但 Warnings 和 Missing Index 提示同样关键)。别被其他数据库的术语带偏节奏——SQL Server 的优化,得按它的规则来。

















