当前位置:首页 > 文章列表 > 数据库 > MySQL > 用 SKIP_SCAN 提示让单表范围条件利用联合索引的后缀列

用 SKIP_SCAN 提示让单表范围条件利用联合索引的后缀列

来源:17golang原创 2026-11-05 11:46:58 0浏览 收藏

如果联合索引的第一列没有出现在条件里,MySQL 通常无法像普通 range 那样直接定位后缀列范围。单表查询可以尝试使用优化器提示 SKIP_SCAN:让优化器跳过联合索引前导列的不同取值,再对后缀列的范围条件分别做子范围扫描。

写法是把提示放在 SELECT 后面,例如 SELECT /*+ SKIP_SCAN(t1 PRIMARY) */ ...。它只是在符合 Skip Scan 条件时强制尝试该访问方法;索引或查询形状不适用时,提示仍可能被忽略,不能把它当成无条件的 FORCE INDEX。

官方地址:https://dev.mysql.com/doc/refman/8.4/en/range-optimization.html

下面用 MySQL 8.4 手册中的同类结构解释提示语义。文章只讨论单表范围条件、联合索引后缀列和 SKIP_SCAN,不延伸到普通索引强制、连接查询或实际压测结果。

为什么没有前导列条件就难以直接做 range

假设表上有联合索引 PRIMARY(f1, f2),查询只写 WHERE f2 > 40。B-Tree 的键顺序先按 f1,再按 f2 排列;没有 f1 的限制时,所有 f1 值混在索引的不同区段里,条件本身不能形成一个连续的单一索引区间。

这不代表后缀列完全没有选择价值。Skip Scan 的思路是把每个不同的 f1 值视为一个前缀,再分别构造 f1 = 某值 AND f2 > 40 的范围。它跳过每个前缀中不满足后缀条件的部分,而不是把整个索引当作一条平面列表逐行过滤。

MySQL 联合索引前导列、后缀范围列与 Skip Scan 静态关系说明图
图1:联合索引结构说明图,展示前导列 f1、后缀范围列 f2 与多个子范围之间的静态关系;这是说明图,不是执行计划截图。

用 SKIP_SCAN 提示指定索引

优化器提示必须写在语句初始关键字之后的 /*+ ... */ 注释中。可以指定表和索引,也可以只指定表让优化器在可用索引中选择。下面的主键由 f1, f2 组成,查询只投影索引中的两列,提示明确指向 PRIMARY:

-- 只查询联合索引覆盖的列,并明确尝试 PRIMARY 上的 Skip Scan
SELECT /*+ SKIP_SCAN(t1 PRIMARY) */
       f1, f2
FROM t1
WHERE f2 > 40;

-- 只指定表时,让优化器在适用索引中选择 Skip Scan 候选
SELECT /*+ SKIP_SCAN(t1) */
       f1, f2
FROM t1
WHERE f2 BETWEEN 40 AND 60;

SKIP_SCAN(t1 PRIMARY) 不是把 f2 变成独立索引,也不是改写 SQL 为很多个 OR 条件。它影响的是当前语句的访问方法候选,实际是否能用仍由索引结构、谓词和代价判断决定。

哪些查询形状适合这个提示

按照 MySQL 8.4 参考手册,Skip Scan 需要联合索引,并且查询只涉及一张表;查询不能使用 GROUP BY 或 DISTINCT,引用的列应当都在该索引中;前导列上的条件需要是常量等值条件(包括 IN()),同时要有后续列的范围条件。对没有显式前导列条件的典型结构,前导部分可以为空,但这并不放宽其它限制。

检查项适合的形状常见不适用原因
表范围单表 SELECT多表 JOIN 或复杂子查询
索引列投影列和过滤列都由联合索引覆盖必须回表读取大量非索引列
谓词后缀列存在 >、只有普通函数条件或无法形成范围
结果形状没有 DISTINCT、GROUP BY需要分组或去重的结果

这里的“适合”是结构上的候选条件,不等于一定更快。前导列的不同值很多、后缀范围很宽时,Skip Scan 仍可能需要访问许多子范围,优化器可能选择其它计划。

MySQL SKIP_SCAN 查询适用条件与 EXPLAIN 观察点静态关系图
图2:适用条件说明图,把单表、覆盖列、后缀范围和计划观察点放在同一张静态关系图中;不是终端或数据库控制台截图。

怎样确认提示真的被采用

先用 EXPLAIN 查看计划的 Extra。官方文档指出,使用 Skip Scan 时通常会出现 Using index for skip scan,对应索引也应出现在 possible_keys 中。这个检查只用于理解计划,不要把提示文字本身当成结果保证。

-- 先查看优化器是否把 Skip Scan 作为访问路径
EXPLAIN
SELECT /*+ SKIP_SCAN(t1 PRIMARY) */
       f1, f2
FROM t1
WHERE f2 > 40;

-- 需要临时关闭 Skip Scan 时,只影响当前会话
SET SESSION optimizer_switch = 'skip_scan=off';

如果 Extra 没有出现该标记,先检查查询是否仍然只读取索引列、是否意外加入了分组或去重、范围条件是否落在正确的后缀列,以及索引名和表别名是否写对。优化器提示只作用于当前语句,而 optimizer_switch 的 skip_scan 标志控制会话范围;语句提示的优先级高于开关,但前提是提示本身适用。

提示被忽略时怎么处理

官方语义是:SKIP_SCAN 会强制优化器尝试指定表或索引的 Skip Scan,但索引对该语句不适用时可以忽略。提示被忽略不应通过不断叠加其它 hint 来“修复”,而应回到查询形状和数据分布。

实际排查可以按三个方向收窄:第一,确认表别名和索引名一致,主键索引使用 PRIMARY;第二,确认 SELECT 的列真的由目标联合索引覆盖;第三,暂时去掉提示对比普通计划,再根据 EXPLAIN 的 key、possible_keys 和 Extra 判断是否值得保留。不要仅凭“用了索引”就推断一定减少了总耗时。

还要注意版本边界。SKIP_SCAN 是优化器提示,不是通用 SQL 语法;部署到不同 MySQL 版本前,应在目标版本的参考手册和实际计划上重新确认。若业务查询后续增加了回表列、连接、分组或排序,也要重新评估,而不是沿用原来的提示。

小结

联合索引的前导列缺少条件时,普通范围访问不能直接把后缀列变成连续区间;Skip Scan 通过枚举前缀值并构造多个子范围,为这类单表查询提供另一种候选访问方式。使用时记住三点:提示写在 SELECT 后,索引和查询必须满足适用条件,最终是否采用要看 EXPLAIN,而不是只看 SQL 写法。

常见问题

SKIP_SCAN 和 FORCE INDEX 是一回事吗? 不是。前者控制 Skip Scan 访问方法,后者限制可用索引;两者解决的问题和适用边界不同。

只要写了 SKIP_SCAN 就一定会出现 Using index for skip scan 吗? 不一定。索引不适用、查询不满足条件或提示引用错误时,都可能看不到该访问方式。

后缀列有范围条件就应该强制 Skip Scan 吗? 不应该。还要考虑前导列基数、范围宽度、是否覆盖索引以及计划代价,先看 EXPLAIN 再决定。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
用左前缀分组索引配合 MIN 直接取得每组最小值用左前缀分组索引配合 MIN 直接取得每组最小值
上一篇
用左前缀分组索引配合 MIN 直接取得每组最小值
区分 UPDATE 必须读取并修改完整记录与 SELECT 的索引条件下推显示
下一篇
区分 UPDATE 必须读取并修改完整记录与 SELECT 的索引条件下推显示
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    892次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    894次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    978次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    965次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    790次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码