用 AI 做 SQL 性能优化建议,怎么避免它给出错误的改写?

第 1212 题 约 2 分钟读完

本文目录
  1. 面试怎么回答
  2. AI 优化 SQL 常见的问题
  3. 正确的做法:给证据,做验证
  4. 把它做成工具

面试怎么回答

AI 优化 SQL 常见的问题是改变语义,比如 NOT IN 改 LEFT JOIN 在有 NULL 时不等价、外连接被改成内连接;不了解数据分布和引擎版本,给出泛泛的建议。我的做法是输入给足证据:SQL、执行计划、各阶段耗时、Shuffle 量、Task 耗时分布、表的统计信息和引擎版本,让它定位真正的瓶颈。输出分成不改语义的参数和配置调整,以及 SQL 改写,改写必须说明为什么等价、前提是什么。上线前一定验证:在采样数据或单分区上对比行数、汇总值和按主键的差异,构造 NULL、重复值、空分区等边界数据,用相同资源对比性能,再走代码评审。可以把采集指标和结果对比做成工具,并跟踪建议的采纳率和效果。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

把一条跑了 2 小时的 SQL 丢给大模型,它很快给出了优化建议:改写子查询、调整 Join 顺序、加 Hint。但改写后的 SQL 跑得快了,结果却和原来不一样。面试官问这题,想看你怎么用 AI 提效,同时守住「结果正确」这条底线。

AI 优化 SQL 常见的问题

  • 语义改变:NOT IN 改成 LEFT JOIN ... IS NULL,在有 NULL 值时结果不同;LEFT JOIN 改成 INNER JOIN 丢了数据;去重逻辑被「优化」掉;
  • 不了解数据分布:建议用广播 Join,但小表其实有几个 GB;
  • 不了解引擎和版本:给出的参数或 Hint 在你的引擎版本里不存在或者已经默认开启;
  • 只看 SQL 文本:没有看执行计划和运行指标,建议是泛泛的「最佳实践」。

正确的做法:给证据,做验证

输入要充分

  • SQL 本身 + 执行计划(EXPLAIN);
  • 运行指标:各阶段耗时、Shuffle 数据量、数据倾斜情况(Task 耗时分布)、溢写;
  • 表的统计信息:行数、分区数、关键字段的基数;
  • 引擎类型和版本、集群资源配置。

这样 AI 能定位真正的瓶颈,比如「第 3 个 Stage 有一个 Task 处理了 80% 的数据,是 Join key 倾斜」。

输出要分类

  • 不改语义的优化:参数调整、加分区过滤(如果原本就该有)、开启 AQE、调整并行度;
  • 改写 SQL:必须说明改写前后为什么等价,以及在什么前提下等价(比如「假设 user_id 不为 NULL」)。

验证必须做

  1. 在采样数据或者一个分区上,对比原 SQL 和新 SQL 的结果:行数、关键字段的汇总值、按主键的逐行差异;
  2. 准备边界数据:NULL、重复值、空分区;
  3. 对比性能时用相同的资源和数据量;
  4. 通过代码评审再上线。

把它做成工具

  • 自动采集执行计划和运行指标,减少人工整理;
  • 内置结果一致性对比脚本;
  • 记录每条建议是否被采纳、优化效果如何,用来评估和改进。