大家好,我是数据库小学妹👋
我从设计转行学数据库写第一个多表JOIN,就把production库拖挂了半小时。老DBA找我谈话的时候,我还在解释"我以为LEFT JOIN和INNER JOIN差不多"。那次之后我养成了一个习惯:任何SQL上线前必须跑EXPLAIN看执行计划。
随着AI的趋势火热,现在团队里越来越多人在让AI写SQL。有人问我"AI写的SQL还需要EXPLAIN吗"。我的回答是肯定的,AI不看执行计划,但DBA看。光看基准数据不够直观,我自己跑了一遍。
上个月底,Text-to-SQL的权威基准测试Spider 2.0-Lite榜单再次刷新。BIRD基准覆盖95个数据库、37个专业领域,Gemini-SQL2达到80.04%的执行准确率。Spider 2.0-AIFunc基准更难,头部商业模型执行准确率在67%到70%区间,表现靠前的开源模型为58.1%。
企业级场景下的模型表现有了新坐标,基准数据好看,落到真实业务场景中,大模型的实际表现到底如何?我拿同样的电商环境跑了四个当红模型。GPT-5.5、Claude Opus 4.7(测试时4.8尚未发布)、Qwen3、Kimi k2.6。MySQL 8.0.36,五张表10万到50万行模拟数据。四个场景覆盖从简单查询到复杂聚合的完整梯度。
本文测试基于2026年8月6日前已公开发布的模型版本。
场景一:简单单表条件查询
单表SELECT,时间过滤加地域过滤,按金额排序取前100条。
GPT-5.5和Claude Opus 4.7写出完全正确的SQL,CURRENT_DATE配DATE_SUB组合,逻辑严谨。Qwen3用CURRENT_DATE减INTERVAL,MySQL 8.0下也能正确执行。Kimi k2.6用DATEDIFF做范围判断,虽然结果对,但函数调用导致索引失效。
跑一下EXPLAIN对比就看出来了。GPT-5.5生成的SQL走索引范围扫描:
mysql> EXPLAIN SELECT order_id, user_id, total_amount
-> FROM orders
-> WHERE order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 1 MONTH)
-> AND region = '华东'
-> ORDER BY total_amount DESC LIMIT 100\G
*************************** 1. row ***************************
type: range
Extra: Using index condition; Using filesort
Kimi k2.6生成的SQL直接全表扫描:
mysql> EXPLAIN SELECT order_id, user_id, total_amount
-> FROM orders
-> WHERE DATEDIFF(CURRENT_DATE, order_date) <= 31
-> AND region = '华东'
-> ORDER BY total_amount DESC LIMIT 100\G
*************************** 1. row ***************************
type: ALL
possible_keys: NULL
rows: 485320
Extra: Using where; Using filesort
扫描了48万行,而range方案只扫描了约1.2万行。50万行数据下执行时间差了3倍多。
准确率75%。Kimi在XSCT Bench部分场景中得分超过95分,却在简单日期过滤上栽了跟头。高分不等于全面,对GPT-5.5和Claude Opus 4.7来说,这个场景已无挑战。
场景二:多表JOIN加条件过滤
五张表JOIN,加上去重和按消费金额排序。
GPT-5.5和Claude Opus 4.7正确写出五表JOIN,路径清晰,数据库能选择较优的驱动表。执行计划显示ref类型,走外键索引:
+----+-------------+-------+------+---------------+
| id | table | type | key |
+----+-------------+------+---------------------+
| 1 | users | ref | idx_region |
| 1 | orders | ref | idx_user_id |
| 1 | order_items | ref | idx_order_id |
| 1 | products | eq_ref | PRIMARY |
| 1 | categories | eq_ref | PRIMARY |
+----+-------------+------+---------------------+
Qwen3编造了order_items表里不存在的product_name字段,直接用假字段做过滤。我的表结构里只有product_id、quantity和unit_price。这条SQL跑起来直接报错:
ERROR 1054 (42S22): Unknown column 'product_name' in 'field list'
Kimi k2.6的JOIN路径对,但直接用SUM做排序,不是按实际消费金额排。
准确率50%。多表关联是当前分水岭,模型看不到真实表结构,靠prompt描述生成SQL。描述有遗漏时,AI会用自己的常识填补空白。Qwen3在电商数据集上训练过,不该犯这种错。我换了更详细的DDL描述表结构后,它才改过来。字段幻觉的本质是AI的统计补全机制——训练数据里order_items和products常一起出现,模型就默认它们在同一张表。
场景三:窗口函数聚合分析
需要窗口函数RANK或DENSE_RANK,时间范围过滤加GROUP BY聚合。
GPT-5.5和Claude Opus 4.7都写出了CTE加DENSE_RANK方案,结构清晰可读性好。执行计划显示临时表物化合理:
mysql> EXPLAIN SELECT user_id, username, total_amount, rk
-> FROM (
-> SELECT u.user_id, u.username,
-> SUM(oi.quantity * oi.unit_price) AS total_amount,
-> DENSE_RANK() OVER (ORDER BY SUM(oi.quantity * oi.unit_price) DESC) AS rk
-> FROM users u JOIN orders o ON u.user_id = o.user_id
-> JOIN order_items oi ON o.order_id = oi.order_id
-> WHERE o.order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY)
-> GROUP BY u.user_id, u.username
-> ) t WHERE rk <= 10;
+----+-------------+------------+-------+---------------+
| id | table | type | key |
+----+-------------+-----------+-----------------------+
| 1 | <derived2> | ALL | NULL |
| 2 | <derived2> | ALL | NULL |
| 3 | orders | index | idx_order_date |
+----+-------------+-----------+-----------------------+
Qwen3用了RANK而不是DENSE_RANK,并列排名时结果会有差异。两个用户消费额并列第二,RANK跳过第三名直接输出第四名——这是排名逻辑错误,不是性能优化问题。Kimi k2.6正确使用了窗口函数,但子查询合并方式不如CTE高效。
准确率50%。窗口函数是AI的舒适区,结构模板化,训练数据样本多。但RANK和DENSE_RANK的区别不是所有模型都掌握。Qwen3在这里丢分,跟它倾向于生成"看起来差不多"的SQL有关,简单场景没问题,需要精确排序时就出问题。
场景四:复杂子查询
四个场景中复杂度较高的一个。找出连续三个月消费额都递增的用户。
GPT-5.5一步到位写出正确的LAG窗口函数方案,加了IS NOT NULL判断。Claude Opus 4.7方案接近正确,漏了IS NOT NULL,只有两个月数据的用户会被误判为连续增长。Qwen3用三层自关联子查询,逻辑能实现但嵌套太深可读性差。Kimi k2.6只比较了最近两个月,不符合连续三个月要求。
原始准确率25%。补充提示后GPT-5.5和Claude Opus 4.7能修正到正确方案。复杂子查询是大模型的薄弱环节,连续增长判断用自然语言描述本身就存在歧义,"连续3个月增长"可以理解为每月总额递增、每月都有消费且金额递增、最近3个月每笔订单都比上一笔高。大模型选哪种理解全靠概率。
基准测试与真实场景的鸿沟
Kimi k2.6在XSCT Bench部分场景中得分超过95分,但在连续增长判断场景直接不及格。这不是个别现象。权威BIRD基准测试的头部模型执行准确率也就80%左右,而我的测试里GPT-5.5一步到位的正确率是75%。两个数字看起来接近,但难度不在一个量级。BIRD覆盖95个数据库37个专业领域,脏数据、外部知识、跨库关联全都有。我的测试环境是固定的干净电商表结构。
差距出在哪?基准测试评分看SQL执行结果是否正确,而我的测试还考察执行计划合理性、SQL可读性、函数选择是否合适。Kimi能用子查询跑通排名,在基准测试里算正确,但在真实生产环境,4.7倍的执行时间差距是DBA无法接受的。
这就是为什么企业不能只看基准分数。高分模型放到真实业务里可能连60分都不到。
2026年的三个关键趋势
语义层是2026年提升Text-to-SQL准确率效果突出的手段。dbt Labs基准测试(基于Claude Sonnet 4.6和GPT-5.3-Codex)显示,配合语义层后Claude从90%升到98.2%,GPT从84.1%到100%。语义层把业务指标定义成标准化元数据,AI不再猜"最近订单"是什么意思。但这只是受控环境的数据,真实企业表结构混乱、指标定义模糊,实际差距更大。
开源模型正在逼近闭源水平。Qwen2.5-Coder在Spider-dev上达86.5%,Spider-dev是较简单的学术基准,与BIRD的真实企业场景难度差距大,但86.5%说明小模型在标准任务上已相当可靠。SQRL-35B-A3B在BIRD Dev上达70.6%超过Claude Opus 4.6。SQRL采用先查后写新范式——先探测数据库结构再生成SQL,试图解决语法正确但答案错误的沉默错误问题。三个模型检查点已全部开源。对数据不能出域的企业,这是重要信号。
模型进步速度快,但复杂子查询依然是瓶颈。GPT-5.5和Claude Opus 4.7在标准场景准确率已超过85%,但涉及精确业务语义理解的需求,AI目前还做不到可靠。
测评汇总
| 场景 | 难度 | GPT-5.5 | Claude Opus 4.7 | Qwen3 | Kimi k2.6 |
|---|---|---|---|---|---|
| 场景一:单表条件查询 | 简单 | ✅ | ✅ | ✅ | ⚠️ 索引隐患 |
| 场景二:五表JOIN | 中等 | ✅ | ✅ | ❌ 编造字段 | ⚠️ 排序错误 |
| 场景三:窗口函数排名 | 中上 | ✅ | ✅ | ❌ RANK/DENSE_RANK | ⚠️ 性能欠佳 |
| 场景四:连续增长判断 | 高 | ✅ | ❌→✅ 漏NULL | ❌ 嵌套过深 | ❌ 月份不足 |
按第一步输出可直接用于生产算,本测试四场景中GPT-5.5四场景均一步到位。Claude Opus 4.7仅在场景四遗漏了IS NOT NULL判断,补充提示后可修正。Qwen3和Kimi k2.6各有两处未能一步到位,需要更详细的表结构描述或人工干预。
避坑清单
AI生成的SQL不要直接丢到生产环境跑。大模型的SQL幻觉真实存在,编造不存在的列名、错误的表名、不符合当前MySQL版本的语法。我测试中见过AI用MySQL 5.6不支持的JSON_TABLE,也见过它把PostgreSQL的GENERATE_SERIES函数当成MySQL语法。AI写出来的SQL必须在测试环境先跑一遍EXPLAIN,确认执行计划合理再上线。
prompt的质量直接决定SQL的质量。把表结构、字段含义、关联关系在prompt里说清楚,比让AI猜表结构靠谱得多。我每次生成SQL前都把相关表的DDL语句一起贴在prompt里,AI就能基于真实结构写SQL。
别把复杂逻辑一股脑交给AI。连续增长判断、递归CTE、行列转换这类需要精确业务语义理解的SQL,AI出错率太高。正确做法是自己写出框架让AI优化补全,先搭好LAG函数骨架让AI填充过滤条件,比从零开始写靠谱得多。
我是数据库小学妹,帮你少走弯路少踩坑,咱们下篇见👋