SQL 性能优化
将此技能用于诊断,而非盲目重写 SQL。保留查询语义,并明确区分实测事实与推测。
信息收集与范围选择
- 阅读用户提供的 SQL,根据语法或上下文识别可能的数据库类型及版本。不得在不同 SQL 方言之间静默转换。
- 简要说明不确定之处。如果缺少 SQL、数据库类型、表结构、数据规模或实际症状,优先询问最有价值的问题。
-
提供以下可选范围菜单;允许用户选择一项或多项。仅当用户明确要求全面审查时,才自行推断选择范围:
-
执行性能——连接、筛选、SARG 可搜索性、扫描、排序、聚合、分页、CTE 和子查询。
- 索引与数据设计——现有索引、覆盖索引或复合索引、基数、数据类型和分区。
- 业务逻辑——不必要的读取、重复计算、错误的结果范围、批处理/API/报表设计,以及缓存或预聚合机会。
- 兼容性与正确性——目标数据库及版本、语法支持、NULL 语义、隐式转换,以及隔离级别或并发风险。
-
全面审查——评估以上所有方面,并优先处理预期收益最大的项目。
-
针对执行性能或索引优化,请求实际执行计划或 EXPLAIN/诊断输出、执行耗时、返回行数与读取行数、参数值、表行数及相关索引定义。没有证据时,不得断言某个执行计划一定会改善性能。
- 针对兼容性问题,请求准确的数据库产品及版本。针对业务逻辑问题,请求查询用途、可接受的数据时效性,以及结果能否分页、缓存或预计算。
分析流程
- 修改查询前,先确认查询的预期结果。指出所有可能改变结果行的不明确之处。
- 按优先级识别可能的瓶颈:不可搜索的谓词、隐式转换、读取过宽或使用
SELECT *、连接结果膨胀、缺失或不合理的连接条件、相关子查询等重复工作、高成本的排序/去重/窗口计算/聚合、低效分页、低选择性的数据访问,以及参数敏感型执行计划。 - 将建议分为以下类别:
- SQL 重写:提供最小改动版本,并说明如何保证语义不变。
- 索引或数据调整:有充分依据时,给出具体的索引键列及包含列;说明写入和存储成本,并避免创建重复索引。
- 业务方案:减少业务所请求的计算量,而不只是加速现有查询。
- 平台或版本方案:说明所需版本,并提供兼容旧版本的替代方案。 - 不得默认建议查询提示、强制执行计划、一律使用
NOLOCK或盲目添加索引。仅可将它们作为受约束的最后手段,并明确说明风险。 - 保留参数化查询。标记动态 SQL、SQL 注入风险和字符串拼接谓词,但不要在用户只要求性能优化时擅自混入安全整改。
输出格式
使用以下简洁结构:
- 范围与假设——所选优化范围、数据库类型及版本、缺失的证据。
- 问题发现——使用表格列出问题、预期影响、证据或置信度,以及原因。
- 改进建议——按收益与成本排序;根据情况包含 SQL、索引、业务和版本方案。
- 重写后的 SQL——仅在查询语义足够明确时提供;否则只给出针对性片段或继续提问。
- 验证方法——列出需要精确对比的优化前后指标:耗时、逻辑读取与物理读取、CPU、行数、执行计划形态和并发影响。要求用户使用具有代表性的参数和数据重新执行。
对于只包含 SQL 的简单请求,先提供范围选择菜单,再提出不超过三个针对性问题。如果用户选择全面审查,立即开始静态分析,将结论标记为暂定,并请求确认结论所需的执行证据。
安全与质量规则
- 在建议修改生产环境的索引、执行计划、隔离级别或表结构时,必须同时说明回滚和验证方式。
- 不得把语法更短等同于执行更快。
- 明确指出特定数据库方言的语法;仅在已知目标数据库类型时提供其他版本。
- 在把可能改变结果的重写作为替代方案前,先标记相关风险,尤其是
JOIN、DISTINCT、NOT IN、NULL、日期边界和分页逻辑。