关于 execution-plan-analysis
用于分析 SQL Server 实际和估算执行计划,尤其是 ShowPlan XML。它帮助数据库开发者和管理员先核验证据,再考虑查询、索引或统计信息调整。
主要功能
- 01实际与估算计划排查
- 02算子成本和行数分析
- 03转换与排序规则检查
- 04估算值与实际值比较
- 05验证分区消除
- 06基于证据提出建议
适用场景
- 01诊断运行缓慢的 SQL Server 查询
- 02检查 .sqlplan 文件
- 03评估索引或统计信息调整
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill execution-plan-analysis安装后在 Claude Code 中输入/execution-plan-analysis确认已加载。
附带文件references/showplan-xml-checklist.md
详细介绍
执行计划分析
使用此技能排查 SQL Server 实际或估算执行计划,尤其是 .sqlplan ShowPlan XML。将计划视为证据,而非结论:在建议重写或添加索引前,先验证架构、数据类型、索引、行数、分区、参数值,以及本地与链接服务器上的执行情况。
所需输入
询问验证计划所需的最少信息:
- SQL Server 版本、数据库兼容级别,以及使用的是 Azure SQL 还是盒装版 SQL Server。
- 如可获取,提供实际计划;若执行存在风险,则提供估算计划。
- 查询文本、参数值、相关的 SET 选项,以及运行时症状。
- 表 DDL、列数据类型、索引、统计信息的更新时间、分区方案/函数,以及行数。
- 引用的对象是本地对象、远程链接服务器、视图、表值函数还是临时表。
- 允许进行的更改:重写查询、更新统计信息、添加/删除/更改索引、添加计算列、使用暂存表,或不更改代码。
使用 ../_shared/optimization-intake.md 和 ../_shared/assumption-tracker.md 收集信息并跟踪假设状态。
工作流
1. 确定计划上下文
记录计划是实际计划还是估算计划。实际计划会显示运行时行数、警告、溢出、内存授予使用情况以及实际分区访问情况。估算计划仍可揭示访问路径、类型转换、缺失索引请求和联接选择,但无法证明运行时估算错误或发生溢出。
记录以下信息:
- 语句子树成本和顶层语句文本。
- 编译时参数值,以及存在时的运行时参数值。
- 可见时,记录基数估算器版本和兼容级别。
- 并行度、内存授予和警告。
2. 排序高成本运算符,然后进行验证
按估算子树成本或运算符成本对运算符排序,以找出可能的工作中心,但不要只根据百分比进行调优。查询很小时,某个运算符即使占比 90% 也可能无关紧要;而重复嵌套循环分支中的低占比运算符也可能主导运行时间。
对每个候选运算符,记录:
| 证据 | 需要记录的内容 |
|---|---|
| 运算符 | 物理运算和逻辑运算 |
| 对象 | 表、索引或远程源 |
| 成本 | 估算运算符/子树成本及相对百分比 |
| 行数 | 估算行数、实际行数、执行次数、读取行数 |
| 谓词 | 查找谓词、残余谓词、探测条件、联接谓词 |
| 警告 | 溢出、类型转换、缺失索引、没有联接谓词、基数问题 |
3. 检查扫描、查找和残余谓词
查找不一定好,扫描也不一定坏。验证读取的数据量与返回的数据量。
- 索引/表扫描:判断这是否是大型结果集查询的预期行为,是否由非 SARGable 谓词导致,是否源于缺少索引,或由类型/排序规则不匹配引起。
- 带残余谓词的索引查找:检查
SeekPredicates与Predicate。如果查找读取数百万行后再进行筛选,可能需要调整键顺序、添加计算列或筛选索引,或者重写查询。 - 键查找/RID 查找:将实际行数乘以执行次数;大量查找可能足以证明覆盖索引的合理性,但不要盲目添加宽大的 INCLUDE 列。
4. 查找隐式类型转换和排序规则问题
在 ShowPlan 中搜索 CONVERT_IMPLICIT、PlanAffectingConvert,以及索引列周围的标量运算符。优先关注谓词和联接中列侧的类型转换,因为它们可能阻止查找或扭曲估算。
对每个类型转换进行分类:
- 仅用于安全投影的类型转换。
- 谓词中的类型转换,可能仍可执行查找,但会损害估算。
- 阻止高效查找的列侧类型转换。
- 导致扫描、哈希联接或远程逐行处理的联接键类型转换。
建议的修复必须保留语义:在允许更改架构时,使参数类型、临时表类型、字面值、计算列或源列定义保持一致。
5. 比较估算行数与实际行数
估算误差较大,可能导致错误的联接顺序、内存授予、溢出和错误的联接算法。
如果任一运算符出现以下情况,请予以标记:
- 实际行数与估算行数相差 10 倍或更多。
- 实际执行次数远超预期。
- 对于表变量、多语句 TVF、局部变量或过时的统计信息,估算为一行但实际返回多行。
- 严重的数据倾斜,表明可能存在参数嗅探或参数敏感计划行为。
建议应针对根本原因:更新统计信息、创建筛选统计信息/索引、使用临时表分阶段获取基数、处理参数敏感性,或重写谓词。
6. 验证分区消除
对于分区对象,确认执行计划是否消除了分区。
检查:
- 分区列及其数据类型。
- 谓词列及其表达式形式。
- 实际或估算访问的分区。
- 转换、函数、OR 谓词、联接、视图或局部变量是否使分区键难以识别。
对于不安全的分区谓词,应发出警告,例如对分区列套用函数、比较类型不匹配的值,或筛选与分区列相关但并非分区列的日期列(除非可信约束能够证明二者等价)。
7. 谨慎解读索引警告
缺失索引警告针对的是某一条已编译语句,只是建议,并非索引设计。只有在与现有索引、工作负载模式、写入成本和约束进行比较后,才将其转化为候选索引。
如果执行计划显示存在更新开销,或问题涉及索引维护,也要检查未使用或重复的索引。不要仅凭单个执行计划建议删除索引;必须有工作负载证据。
8. 以证据形式报告发现
使用以下格式:
- 计划摘要:计划类型、语句、运行时症状、主要运算符。
- 已验证事实:已确认的架构/索引/类型/行数事实。
- 发现:逐项列出运算符、XML 证据、影响和置信度。
- 假设:标记为已验证、未验证、已排除或需要诊断。
- 建议:优先选择最安全的方案;分别列出重写、索引/统计信息变更和诊断。
- 验证计划:收集优化前后的指标。
参考
有关 ShowPlan XML 属性、XPath 风格的查找以及运算符成本解读,请参阅 references/showplan-xml-checklist.md。