关于 query-optimization
面向 SQL Server 和 Azure SQL Database 的查询优化技能,供数据库开发者和管理员依据结构与执行证据定位瓶颈,并验证改动的正确性和性能。
主要功能
- 01先核实架构并追踪假设
- 02分析执行计划与 I/O 瓶颈
- 03检查 SARGability 和数据类型
- 04验证连接与改写的等价性
- 05指导参数敏感性与统计信息
- 06按结构输出建议和风险
适用场景
- 01排查 SQL Server 慢查询
- 02验证改写前后的结果等价性
- 03评估索引或统计信息变更
- 04诊断参数敏感型工作负载
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ josiahsiegel/ claude-plugin-marketplace --skill query-optimization安装后在 Claude Code 中输入/query-optimization确认已加载。
附带文件references/dmv-diagnostic-queries.mdreferences/rewrite-proof-harnesses.md
详细介绍
查询优化
面向 SQL Server 和 Azure SQL Database 的 T-SQL 查询优化综合指南。基于已验证的证据进行优化:架构、数据类型、索引、行数、分区、执行计划以及允许的变更类型。
强制工作流
1. 优先验证架构
在建议改写、索引或提示之前,请先核实以下信息;无法核实时则标记为未知:
- SQL Server 版本、版本类型、兼容级别,以及适用时的 Azure SQL 层级。
- 完整的查询/过程文本、参数值、执行频率和运行时间目标。
- 表、视图、临时表、表变量和 TVF 的 DDL。
- 连接、筛选、分组、排序和临时表列的数据类型,包括长度、精度、小数位数、排序规则和是否可为空。
- 现有索引、约束、统计信息的更新时间、分区函数/方案以及行数。
- 对象是本地对象,还是链接服务器/远程数据源。
- 允许的变更类型:查询改写、新建索引、超大表索引变更、更新统计信息、暂存表、计算列,或不改代码。
使用 ../_shared/optimization-intake.md 和 ../_shared/assumption-tracker.md。如果缺少关键信息,请提供附带诊断步骤的条件性指导,而不是给出最终建议。
2. 找出根本瓶颈
尽可能使用实际执行计划和 STATISTICS IO, TIME。按测量出的影响排序,而不仅仅依据执行计划中的估算百分比:
- 逻辑读取量或行读取量过高。
- 估算值与实际值之间存在较大偏差。
- 由非 SARGable 谓词或缺少访问路径导致的扫描。
- 执行次数过多的键查找。
- 因估算不佳或缺少排序顺序而导致的排序/哈希/窗口溢出。
- 远程查询未能将谓词或连接下推到链接服务器。
如需详细检查 .sqlplan,请加载 tsql-master:execution-plan-analysis。
3. 修复 SARGability 问题和类型不匹配
SARGable 谓词可以使用有序索引访问。避免对索引列使用函数或进行类型转换。
| 非 SARGable | 更安全的写法 |
|---|---|
WHERE YEAR(OrderDate) = 2026 | WHERE OrderDate >= '20260101' AND OrderDate < '20270101' |
WHERE LEFT(Name, 3) = 'ABC' | WHERE Name LIKE 'ABC%' |
WHERE Amount * 1.1 > 1000 | WHERE Amount > 1000 / 1.1 |
WHERE CONVERT(date, Dt) = @d | WHERE Dt >= @d AND Dt < DATEADD(day, 1, @d) |
WHERE VarcharCol = 123 | WHERE VarcharCol = '123' |
请检查实际数据类型。即使谓词在语法上符合 SARGability,如果参数、临时列或连接键的类型或排序规则不正确,仍可能触发扫描。
4. 验证连接变更
切勿仅因所选列来自某个表就删除或替换连接。请验证:
- 连接是否会筛掉行? 比较基础行数和连接后的行数,并检查外键是否受信任。
- 连接是否会增加行数? 检查连接键是否唯一,以及被引用表中是否存在重复值。
- 能否替换为
EXISTS? 如果只需判断是否存在且必须避免行数增加,请使用半连接。 - 是否保留外连接?
WHERE中的谓词可能会意外地将LEFT JOIN转换为内连接。
请将移除连接的实验放入验证框架,并使用双向 EXCEPT 验证结果等价性。参见 references/rewrite-proof-harnesses.md。
5. 检查临时表和暂存数据类型
临时表通常是合适的优化工具,但类型不正确可能导致隐式转换。
在使用或建议使用临时表之前:
- 将暂存列类型与源元数据进行比较。
- 连接/筛选列的字符串长度和排序规则应与源列一致。
- 数值精度/小数位数和日期/时间精度应与源列一致。
- 加载后,如果行数足以支持,应添加适当的聚集或非聚集索引。
- 如果分阶段优化依赖准确的基数估算,请更新临时表统计信息。
请将不匹配项列为首要问题,因为它们可能导致执行计划分析和索引建议失效。使用 references/rewrite-proof-harnesses.md 中的检查器。
6. 选择改写模板
选择能够解决已验证瓶颈且侵入性最低的改写方式:
| 情况 | 模板 |
|---|---|
| 大型联接前有高选择性的谓词 | 先暂存符合条件的键,为暂存数据建立索引,然后再联接。 |
| 大型明细表稍后才聚合 | 如果分组能保留语义,则尽早聚合。 |
| 联接仅用于测试是否存在 | 用 EXISTS 替换会生成行的联接。 |
| 对不同列使用 OR | 拆分为带重复项保护的 UNION ALL 分支。 |
| 包罗多种情况的可选谓词 | 使用动态 SQL 或针对性重新编译;避免在高频路径中使用 Col = @p OR @p IS NULL。 |
| 不安全的分区谓词 | 改写为分区列上的直接类型化范围条件。 |
| 表变量/TVF 导致估算不佳 | 根据版本和工作负载,使用临时表、内联 TVF 或重新编译。 |
除非已证明行数会减少且语义等价,否则不要暂存未经筛选的大型表,也不要提前聚合。
参数敏感性
当为某个值编译的计划被用于另一个截然不同的值时,就会发生参数嗅探。应用修复前,请先确认数据偏斜以及编译值/运行时值。
| 选项 | 最适用场景 | 注意事项 |
|---|---|---|
OPTION (RECOMPILE) | 不常执行或变化极大的语句 | 会增加编译 CPU;计划不会复用。 |
OPTIMIZE FOR (@p = value) | 具有稳定代表值的场景 | 随着数据变化,效果可能变差。 |
OPTIMIZE FOR UNKNOWN | 平均分布可接受的场景 | 对所有情况而言,效果可能都一般。 |
| 动态 SQL | 可选谓词和多种查询形态 | 需要安全地参数化。 |
| Query Store 提示 | SQL Server 2022+ 或 Azure SQL,且无需更改代码 | 监控回退问题。 |
| PSP 优化 | SQL Server 2022+,且兼容级别为 160 | 仅适用于符合条件的模式。 |
执行计划检查
关注以下运算符和警告:
| 计划证据 | 可能采取的措施 |
|---|---|
| 带残余谓词的扫描 | 修复 SARGability、键顺序或筛选索引。 |
| 读取行数较多的查找 | 增加更具选择性的键列,或改写残余谓词。 |
| 多次重复的键查找 | 覆盖查询,或先减少外部行数。 |
| 排序溢出或哈希溢出 | 修正估算、减少行数/宽度,或添加顺序兼容索引。 |
列上出现 CONVERT_IMPLICIT | 统一参数/临时表/源数据类型。 |
| 估算偏差达到 10 倍以上 | 检查统计信息、数据偏斜、表变量、谓词和约束。 |
| 缺失索引警告 | 仅将其视为候选项;与现有索引及工作负载一并评估。 |
统计信息和基数
当证据表明估算过时或不足时,使用统计信息相关措施:
DBCC SHOW_STATISTICS('dbo.TableName', 'IndexOrStatsName');
UPDATE STATISTICS dbo.TableName IndexOrStatsName WITH FULLSCAN;
对于大型分区表,请评估增量统计信息和筛选统计信息。未考虑维护时段和阻塞问题时,不要在生产环境中运行大范围的全扫描更新。
输出格式
请按以下格式作答:
- 接收状态:已验证、未验证、已证伪、需要诊断。
- 瓶颈证据:计划节点、读取量、行数、估算值、警告。
- 建议路径:改写、索引/统计信息变更或诊断,并按允许的变更类型分别列出。
- 验证方案:结果等价性以及变更前后的性能指标。
- 风险:参数敏感性、写入开销、阻塞、分区安全性、远程下推。
参考资料
../_shared/optimization-intake.md- 必须完成的接收检查清单。../_shared/assumption-tracker.md- 假设状态协议。references/rewrite-proof-harnesses.md- 联接验证、临时类型检查器和改写模板。references/dmv-diagnostic-queries.md- 用于性能分析的 DMV 查询。