凌晨两点半,群里的告警又响了。我打开慢查询平台,一眼扫过去,排在前面那条SQL我还是有点印象的——昨天刚有开发同学来问过,为什么一个简单的列表查询要跑两秒多。我看了看表结构,status字段上有索引,但开发在SQL里写了WHERE status != 1,索引直接失效,全表扫描。这种问题不算难排查,但每一次都要人工去看、去解释,耗时耗力。
后来我就在想,能不能做一个工具,让开发同学在写SQL的那一刻就有一个“懂行的人”在旁边提醒?或者更进一步,他们直接用大白话描述需求,工具自动生成SQL并提前发现性能隐患?这个想法就是 DB-AI 的起点:一个面向开发者的智能数据库助手,把自然语言查询、SQL性能诊断、索引建议、影响面分析这些能力,打包成开发阶段就能用起来的工具链。
这个项目我从零搭到了能在团队里日常使用的程度,中间踩了不少坑,也沉淀了一些设计上的取舍。这篇文章就把我的思路、实现路线和踩坑过程完整写出来,给同样想做数据库智能化工具的团队一个参考。
1. 为什么我会亲手做一个数据库智能助手
1.1 开发同学和DBA之间的信息差
先聊一个很现实的问题:开发同学真的不懂数据库吗?不完全是。大多数后端开发能写CRUD,能建索引,但一旦遇到执行计划、锁等待、隐式类型转换、索引失效这些偏底层的概念,就容易卡壳。而DBA呢,懂这些,但DBA的数量永远比开发少一个数量级,不可能每一条SQL都人工去看。
这个信息差带来的后果就是:SQL性能问题在开发阶段没有被发现,等上线到了生产环境,流量一大就爆发。然后DBA半夜被叫起来,看一眼慢查询,发现又是一个低级问题,只能叹口气,截图发给开发,再写一段几百字的解释。整个过程非常低效。
我之前维护过一套日活百万的线上系统,对这种痛感特别深。统计过一个月的慢查询日志,发现排名前二十的慢SQL里,有将近一半的问题属于“可选索引没走到”这一类,包括WHERE条件里对索引列做了函数运算、OR连接导致索引失效、字符集不一致导致的隐式转换等。这些问题只要在写SQL的时候有人提醒一句,就能避免。
1.2 数据库AI工具的现状与空白
大模型流行起来之后,市面上确实出现了不少“NL2SQL”工具,用自然语言直接生成SQL。但这类工具普遍有个问题:它们更关注“能不能把SQL生成出来”,而不是“生成的SQL在真实数据库里能不能高效执行”。
我自己试用过几个开源方案,发现几个共性问题:
- 工具能生成语法正确的SQL,但完全没有考虑这张表的索引情况
- 生成的SQL嵌套过深,连接了七八张表,执行计划一眼看去就是灾难
- 没有结合公司的库表规范,比如必须带
LIMIT、不允许SELECT *、禁止UPDATE不带WHERE等 - 对生产环境的数据字典、字段注释没有感知
所以DB-AI从一开始的定位就不单纯是“生成SQL”,而是一个覆盖SQL全生命周期的开发辅助工具:写之前帮你理解数据字典,写的过程中用自然语言生成SQL并校验性能,写完之后再走一遍静态检查、执行计划分析和慢查询日志关联诊断。这条路线做下来,开发同学能自己搞定大部分日常取数和性能排查需求,DBA也能从重复解释中解放出来。
1.3 项目目标与适用人群
DB-AI适用的场景很明确:
- 后端开发:日常取数、临时数据分析、排查慢SQL
- 数据研发:数据仓库建模时的表结构理解、ETL脚本里的SQL质量检查
- DBA/运维:用AI辅助批量分析慢查询,减少重复性解释工作
- 测试/产品:不写SQL,但偶尔需要查数据验证功能的同学
面向的使用形态也考虑了好几种:命令行工具、IDE插件、内部API服务。后面我会专门讲落地形态怎么选。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. DB-AI设计时先想清楚的边界问题
2.1 什么该做,什么不该做
做AI工具最容易犯的错就是“什么都要管”,最后什么都做不好。DB-AI在设计初期就和团队定了几条原则:
该做的:
- 只读查询类需求:自然语言转SELECT语句,并做性能预估
- SQL静态分析:在代码评审阶段发现明显的性能问题
- 慢查询日志分析:聚合线上慢SQL,按根因分类,输出修复建议
- 元数据理解:解析表结构、索引、字段注释,辅助开发理解数据字典
- Schema变更影响面分析:一个字段要改名,找出哪些视图、存储过程、报表会被影响
不该做的:
- 不直接执行生产环境的写操作,一切写入类操作必须走工单系统
- 不替代人工DBA做最终决策,AI只给建议,不给“一键执行”
- 不连接生产库做实时分析,只通过只读从库或者定时同步的元数据仓库来分析
这套边界划定之后,后面的架构设计和权限模型都有了依据,团队用起来也放心。
2.2 核心使用场景拆解
从用户视角看,DB-AI主要覆盖下面几个场景:
| 场景 | 传统做法 | DB-AI做法 | 收益 |
|---|---|---|---|
| 临时取数 | 开发自己写SQL,翻数据字典 | 自然语言描述需求,AI生成SQL并附执行预估 | 减少数据字典查阅时间,降低SQL出错率 |
| 慢SQL排查 | 找DBA要执行计划,等人工解释 | 丢入SQL,AI自动解析执行计划并定位根因 | 从小时级降到分钟级 |
| 上线前检查 | 靠经验review SQL | IDE插件在提交前自动跑静态规则 | 把问题拦截在开发阶段 |
| 字段变更评估 | 人工搜索所有引用 | 元数据血缘扫描,输出影响清单 | 避免漏改导致线上故障 |
我特别想强调上线前检查这个场景。很多团队把SQL Review放在代码评审阶段,但代码评审的同学往往也是开发出身,对数据库性能问题的敏感度不一定够。与其指望人,不如把规则自动化——这比用大模型更可靠,因为静态规则是确定性的,不会今天判有问题明天又放行。
2.3 为什么不直接用现成NL2SQL开源项目
这里我想多说两句。最开始我也想过直接拿一个开源NL2SQL项目来改,省时省力。但调研之后放弃了,原因有三。
第一,开源项目对私有化数据字典的支持太弱。公司的库表名、字段注释很多是历史遗留的,字段命名不规范,必须额外维护一套元数据映射才能让模型理解。第二,安全审计能力不够。我需要每个查询都能追溯、可审计,而大多数NL2SQL工具只是个“问答工具”,没有操作审计链路。第三,性能诊断能力缺失。这是最关键的一点,我要的不只是“SQL能跑”,而是“SQL跑得快”。现成工具没有执行计划解析、索引推荐、历史慢查询关联分析这些能力,而这些恰恰是对开发最实用的功能。
当然,不开源项目也不是全盘否定。我在底层文本转SQL这个环节,参考了很多优秀项目的做法,然后自己再做了一层封装和增强。这个思路也给各位一个参考:AI能力可以踩在巨人肩膀上,但产品能力一定要自己做深。
3. DB-AI的核心架构与实现思路
3.1 整体分层设计
DB-AI的整体架构分四层,每一层各司其职:
接入层:统一对外提供接口,包括CLI命令、IDE插件调用、REST API三种形态。这一层做的事情主要是参数校验、用户认证、操作审计。
解析与增强层:这是整个系统的中枢。收到自然语言问题或者SQL文本后,先做SQL解析(如果是SQL直接进入诊断流程),再做上下文召回,把相关表结构、索引信息、字段注释、历史相似查询封装成上下文,供LLM调用。
诊断与分析引擎:包括NL2SQL生成器、SQL静态检查器、执行计划解析器、慢查询聚类分析器四个核心模块。
数据基座层:维护从各数据库实例同步过来的元数据仓库,包括表结构、索引、分区、字段注释、统计信息、历史慢查询样本库。
整体流程可以这样理解:用户的需求先进入接入层,解析与增强层负责把“模糊的问题”变成“结构化的上下文”,然后诊断引擎基于上下文给出SQL和诊断结果,最终把结果通过接入层返回给用户。
3.2 SQL解析为什么选sqlglot
项目里要同时支持MySQL、PostgreSQL,前面还碰到过ClickHouse的查询,所以SQL解析器必须支持多方言。我对比了ANTLR4和sqlglot两个方案。
ANTLR4更底层、更强大,但需要为每种方言维护语法文件,学习成本高,而且就我们这个项目来说,用不到那么深层的语法定制能力。sqlglot是纯Python实现,内置了多种方言解析,可以把一种方言的SQL转成另一种方言,最方便的是它提供统一的AST和表达式遍历接口,这对做静态检查非常友好。
实际用下来,sqlglot的parse_one就能把SQL解析成语法树,然后通过ast属性遍历所有的表、列、条件表达式。比如检查SELECT *:
python复制from sqlglot import parse_one
sql = "SELECT * FROM orders WHERE status = 1"
ast = parse_one(sql)
# 遍历所有选中的列
for select_expr in ast.find_all(exp.Select):
for col in select_expr.expressions:
if isinstance(col, exp.Star):
print("发现 SELECT *,建议显式列出字段")
再比如检测隐式类型转换,可以检查条件表达式两侧的字段类型是否一致,这需要先查元数据仓库,拿到字段的类型再做比对。
3.3 自然语言转SQL的实现路线
自然语言转SQL是DB-AI里用户感知最强的一个功能点,也是踩坑最多的地方。
我设计的生成链路分四步:
第一步:意图识别与表定位。 先把用户的问题做意图分类,是“查数据”还是“问结构”,还是“查性能”。如果是查数据,下一步就是从元数据仓库里召回相关表。这一步我用的是向量检索加关键词命中的混合方式:先对表名、字段名、字段注释做embedding,存到向量数据库里;用户问题来了之后,用同一个embedding模型编码,按相似度召回Top K张表,再用关键词做一次过滤,避免向量召回跑偏。
第二步:Schema信息组装。 召回到相关表之后,把表结构、索引、字段注释、枚举值、最近的历史查询样本,一起拼成Prompt上下文。这里有个关键点:Prompt里的Schema信息不能太全,否则会稀释模型的注意力,SQL生成会更不准。我一般控制在一张表的相关字段不超过15个,如果字段太多,优先带上有注释的字段和与问题关键词相关的字段。
第三步:LLM生成SQL。 模型选择上,我用了两种路线并行:小问题走自建的开源模型服务(qwen等),准确度要求高的场景走云端商用API。生成的时候会传一个包含“规则约束”的System Prompt,比如“只允许SELECT操作”“必须带LIMIT”“不允许SELECT *”“表名带库名前缀”等。
第四步:生成结果校验与修复。 SQL生成完不是直接返回给用户,先过一遍静态检查。用sqlglot解析AST,校验表名、列名是否真实存在于元数据仓库,是否存在多个表Join但没带Join条件(笛卡尔积风险),是否缺少LIMIT。如果校验发现问题,把错误信息回传给LLM做一轮修复。修复超过两轮就直接拒绝,把错误提示返回给用户。
python复制def validate_generated_sql(sql: str, metadata: dict) -> dict:
"""对生成SQL做安全性、规范性校验"""
issues = []
try:
ast = parse_one(sql, dialect=metadata.get("dialect", "mysql"))
except Exception as e:
return {"pass": False, "issues": [f"SQL语法错误: {e}"]}
# 检查只读
if ast.find(exp.Insert) or ast.find(exp.Update) or ast.find(exp.Delete):
issues.append("只允许SELECT查询")
# 检查 LIMIT
if not ast.find(exp.Limit):
issues.append("请务必添加LIMIT限制返回行数")
# 检查 SELECT *
for star in ast.find_all(exp.Star):
issues.append(f"第{star.line}行: 不建议使用SELECT *")
# 检查列名存在性
for column in ast.find_all(exp.Column):
col_name = column.name
# 从元数据缓存中校验
if not metadata["columns"].get(col_name):
issues.append(f"列名 `{col_name}` 不存在,请确认字段名")
return {"pass": len(issues) == 0, "issues": issues}
3.4 慢查询诊断引擎的处理逻辑
慢查询诊断是DB-AI里最“硬核”的部分,因为这里是确定性的规则在起作用,不依赖大模型的“自由发挥”,所以结果稳定可靠。
诊断引擎的数据来源有两个:一是用户主动提交的SQL文本,二是数据库慢查询日志定期同步。
对于用户主动提交的SQL,流程是这样:先解析SQL,拿到涉及的表和WHERE条件;然后到元数据仓库查这几张表的索引情况;再用sqlglot分析WHERE条件里是否对索引列做了函数运算、隐式转换等;最后把执行计划(如果用户提供了EXPLAIN)解析成结构化JSON,逐项打标。
慢查询日志的来源处理更复杂一点。MySQL的慢查询日志是文本格式,先用定时任务解析成结构化记录,提取SQL指纹(把字面量替换成占位符),再按指纹聚合。聚合之后,同一个指纹的慢SQL会合并成一条,统计出次数、平均耗时、最大耗时、涉及的库表,然后进入根因分类流程。
这里给出一个分类逻辑的示例:
| 根因分类 | 判断条件 | 修复建议 |
|---|---|---|
| 索引缺失 | 执行计划出现大表全表扫描,且WHERE条件字段无索引 | 给出创建索引的DDL建议 |
| 索引失效 | WHERE条件对索引列做了函数运算或隐式类型转换 | 建议改写为索引列原始形式 |
| 查询返回数据量过大 | 单次返回行数超过阈值 | 建议分页或增加LIMIT |
| 锁等待 | 执行计划显示长时间锁等待 | 建议优化事务隔离级别或缩小事务范围 |
| 多表连接顺序不当 | Join顺序和驱动表选择不佳 | 建议用小表驱动大表,改写Join条件 |
诊断引擎的输出是一个结构化的诊断报告,包含执行计划可视化、风险点列表、修改建议、等价改写SQL。开发同学拿到这个报告,基本不用再问DBA就能自己改了。
4. 开发过程中踩过的那些坑
4.1 大模型的SQL幻觉问题
这是所有NL2SQL工具都无法绕开的坑。所谓幻觉,就是模型生成SQL时用了一个不存在的列名,或者凭空想出来一张表。我统计过,早期版本里大约有15%到20%的生成SQL存在不同程度的幻觉问题。
后来采用的解法是“强约束加后置校验”双保险。
- 强约束:生成SQL之前,在Prompt里明确列出可用的表和字段列表,并声明“禁止使用列表之外的字段名”
- 后置校验:生成的SQL用sqlglot解析出所有引用的列名,和元数据仓库比对,一旦发现不存在的列名,自动标识错误并触发修复重试
试过之后,幻觉比例降到了3%以下。但完全清零不太现实,所以最终产品里,所有生成SQL都保留了“可追溯”标记,用户能清晰地看到这条SQL引用了哪些表和字段,每个表结构是从哪里来的。信任问题要用机制解决,不能用人品解决。
4.2 元数据质量差导致的召回效果偏差
向量召回表的效果,严重依赖元数据本身的注释质量。实际情况是,很多老表的注释是空的,或者写的是“字段1”“字段2”这种毫无信息量的内容。模型没有上下文,自然就不知道这张表是干什么的。
解决思路是“补全+同义词”两步走。
- 数据字典补全:从数据仓库的血缘关系里,反向推断字段含义。比如一张
user_order表里有个amt字段,如果它关联了财务域的订单表,那可以推断amt大概率是金额类字段。 - 同义词映射:维护一份同义词表,把用户口语里的词和字段名对应起来。比如用户说“用户”,可以映射到
user_id、uid、member_id等多个字段。这一步非常朴素,但效果出奇地好。
也有人问我,要不要用更大的模型“智能推断”字段含义。我的体会是,在元数据质量差的场景下,先做规则补全比直接上大模型更稳,因为规则的结果是可以预期和迭代的,大模型的推断则会有不确定性,反而难排查。
4.3 方言兼容性比想象中更难
项目初期只在MySQL上跑,后来要接PostgreSQL和ClickHouse,方言兼容性问题就暴露出来了。最典型的是分页语法:MySQL是LIMIT offset, count,PostgreSQL也是LIMIT但推荐OFFSET写法,ClickHouse则是LIMIT语义和MySQL接近,但聚合语法差异挺大。
sqlglot提供了方言转换能力,可以统一把用户输入的方言解析成标准AST,再转换成目标方言。实践下来,大多数SQL语法可以通过sqlglot的dialect参数正确处理,但某些特殊语法(比如ClickHouse的ARRAY JOIN)还是存在误解析的情况。我的处理方式是给每个数据库实例打一个方言标签,在诊断引擎里按方言走不同的分支;遇到sqlglot无法解析的SQL,就降级走正则表达式做基础检查,而不是直接报错。
这个经验也说明,做数据库工具,必须做好和“脏SQL”长期共存的准备。生产环境的SQL不是教科书,各种历史写法都有,解析器要能容错。
4.4 多表Join生成SQL容易失控
自然语言生成SQL时,LLM容易把需求理解复杂,一次性Join五六张表。比如用户问“统计上个月各地区的销售额TOP10产品”,模型可能就把订单表、订单明细、产品、地区、分类、员工全连进来了。这些SQL看起来逻辑完整,但实际跑起来,性能惨不忍睹。
为了控制这种趋势,我在生成约束里加了几个硬性规则:
- 默认最大允许Join的表数为4张,超了就提示用户“需求是否可以拆成多个查询”
- 如果Join条件中没有用到索引字段,给出警告
- 生成结果附上“预估涉及行数”,让用户对查询成本有感知
还有一个比较有效的技巧是**“分步生成”**:如果用户的需求比较复杂,先让LLM把它拆成多个子问题,分别生成SQL,再给出子结果之间的关联关系。这种方式比一次生成一条大SQL更可控,也更符合开发同学平时排查问题的思维习惯。
4.5 权限与审计设计
DB-AI要接入公司内部使用,权限和审计就绕不开。
权限方面,我做了两级控制。
- 数据源权限:不同的数据库实例,只对特定团队开放。开发同学只能查到自己有权限的库,不能因为用了AI工具就绕过了原有的权限体系。
- 操作权限:区分“执行查询”和“仅生成SQL”两种模式。有些场景下,用户只想要SQL文本,不想在工具里直接跑,因为有些查询太重,会拖垮数据库。
审计方面,每一个请求都会记录:用户ID、时间、输入的自然语言或SQL、生成的SQL、最终执行状态、结果行数。这些日志单独存一份,按天归档。一旦出现数据泄露或者误操作,可以快速追溯到责任人。
5. 落地形态选择与团队推广经验
5.1 CLI、IDE插件还是Web服务
产品做出来了,总要有一个让用户愿意用的入口。DB-AI我做了三种形态,分别对应不同场景。
CLI工具:适合终端党,一条命令直接跑,dbai query "最近一周订单总量",输出SQL和结果。开发同学排查问题的时候不用离开终端,熟练之后效率很高。缺点是可视化能力弱,执行计划展示只能靠文本。
IDE插件:这个形态在VSCode里做,最核心的能力是“选中一条SQL,右键点击诊断”,直接在编辑器里看到痛点提示。这个使用场景覆盖了开发同学写代码时的真实需求。插件调用后端的REST API,不自己执行本地计算,保证逻辑一致。
Web/API服务:主要给内部平台集成用,比如我们的研发效能平台会在MR合并之前调用DB-AI的SQL检查接口,自动拦截有问题的SQL。另外也给数据团队做了一次性的慢查询体检报告。
三种形态的维护成本不一样,但底层共用同一套后端服务。我的建议是,刚开始做的时候只做一个形态,把逻辑跑通,再加第二个、第三个。我自己就是先把CLI做到能用,然后才做的IDE插件,Web服务放在了最后。
形态不同,推广策略也不同。
| 形态 | 优势 | 适用人群 | 推广重点 |
|---|---|---|---|
| CLI | 操作快、适合脚本化 | 后端研发、DBA | 命令自动化、与终端工作流结合 |
| IDE插件 | 上下文感知强、可视化好 | 大多数开发同学 | 代码评审前检查、实时诊断 |
| Web/API | 可集成到平台流程 | 平台组、数据组 | CI/CD流水线集成、定时巡检 |
5.2 让团队真正用起来的关键
工具做完了,最怕的就是没人用。我有几个实操上的心得。
第一,先提供确定性强的功能,再上AI功能。我在推广的时候,最先让团队用的是SQL静态检查,因为这个结果是确定性的,说“这句SQL有笛卡尔积风险”就是有,不会今天报明天不报。团队建立起信任之后,再推广自然语言转SQL这种AI功能,接受度就高很多。
第二,建立团队的SQL样本库和评测集。我们从线上慢查询日志里挑了几百条典型SQL,再配合一些业务问题,形成了一个评测集。每轮模型升级都要先在评测集上跑一遍,看“SQL可执行率”“正确率”“人工修改率”三个指标的变化。没有这个评测集,迭代就是盲人摸象。
第三,给用户一个“反馈和纠错”的入口。AI生成的SQL如果错了,用户能一键反馈,这个反馈会进入样本库,成为后续优化的重要素材。一开始收集到的反馈质量参差不齐,但慢慢积累,样本库就会变成团队的知识资产。
5.3 一个日常使用的示例
这里放一个CLI工具的日常使用示例,让大家直观感受一下。
bash复制# 用自然语言查询
$ dbai query "查询上个月每天的新增用户数,按日期排序"
生成SQL:
SELECT DATE(created_at) AS dt, COUNT(DISTINCT user_id) AS new_users
FROM user_register_log
WHERE created_at >= '2025-02-01' AND created_at < '2025-03-01'
GROUP BY DATE(created_at)
ORDER BY dt
LIMIT 100;
诊断结果:
- 字段 user_register_log.user_id 存在索引 idx_user_id
- 查询条件 created_at 使用了索引列,但未加时间范围上限,建议确认业务是否允许
- 预估扫描行数: 约 150 万行
是否执行查询?(y/n):
bash复制# 诊断一条慢SQL
$ dbai diagnose "SELECT * FROM orders WHERE status != 1 AND created_at > '2025-01-01'"
诊断结果:
1. 发现 WHERE 条件中的 status != 1 会导致索引失效,因为不等于操作无法使用普通B+树索引
建议改写: SELECT * FROM orders WHERE status IN (0,2,3,4) AND created_at > '2025-01-01'
2. SELECT * 查出了全部字段,包含 text 类型的大字段,建议改为只查询列表展示需要的字段
3. 该表存在 idx_created_at 索引,可以覆盖时间过滤条件
开发者拿到这个结果,基本自己就能改了,不需要再来找DBA。
6. 从诊断到治理的演进路线
6.1 接入CI流水线,把SQL问题拦截在合并之前
目前DB-AI的定位更多还是“开发阶段的辅助工具”。我计划中的下一步,是把SQL检查能力接入CI流水线。
具体做法是:在Merge Request的流水线里加一个Job,检测变更文件中包含的SQL语句,把每一条SQL都送到DB-AI的静态检查接口。如果检查出“高优先级风险”,直接阻断合并;如果是“中低风险”,以警告形式展示,允许人工确认后合入。
这个想法落地的难度不在于技术,而在于团队对“自动化拦截”的接受程度。刚开始肯定会有开发觉得“为什么我的SQL不能合入”,所以规则的制定要公开透明,并且留一个“管理员白名单通道”作为例外处理手段。这些规则本身也要跟着业务和数据库的实际情况迭代,不能一套规则用到底。
6.2 与监控告警系统联动
另一个我想做的方向是,把DB-AI的诊断引擎和线上监控系统联动。当监控发现一条慢查询时,不只推送“这条SQL慢了”,而是在告警详情里直接附上DB-AI的诊断报告:为什么慢、索引情况、改写建议、是否在历史上出现过类似问题。
这么做有两个好处。一是减少DBA的重复劳动,不用每次告警都人工分析一遍;二是把“故障响应”变成“知识积累”——每次告警的诊断结果都会进入样本库,下次再出现类似的问题,直接就能匹配到历史案例。
6.3 一些真实的体会
做到这一步,回头看这个项目,最深的感受是:智能数据库助手这类工具,难点不在AI模型本身,而在工程化落地。
大模型技术在飞速进步,今天看起来很难的NL2SQL问题,明天可能就被新的模型解决了。但把SQL解析、元数据管理、执行计划分析、权限审计、团队工作流这些工程问题做好,是需要长期沉淀的。AI给的是“智能”,工程给的是“可靠”,两者缺一不可。
如果你也想做类似的项目,我的建议是:不要一上来就追求大而全,先围绕一个你团队最痛的点做透。比如先做一个“慢SQL自动诊断”,跑通之后再慢慢加上自然语言查询、索引推荐、血缘分析这些能力。小步快跑,在真实使用中迭代,比一次性憋一个大版本要靠谱得多。
最后分享一个小技巧:多留一点时间做评测集。没有评测集,你都不知道模型更新之后是把SQL生成准确率提高了还是改坏了。评测集就是这类AI工具的地基,前期花的时间后面都会赚回来。
