自然语言取代SQL的可能性?
点击标题下「蓝色微信名」可快速关注
技术社群的这篇文章《人机协奏曲:当 LLM 遇上 SQL,谁是完美的合奏者?》给我们带来了Victor Ramirez Garcia和Alberto Romeu的这篇文章译文,针对LLM和SQL的共存问题进行了探讨。
原文链接:
https://www.tinybird.co/blog/which-llm-writes-the-best-sql
自然语言能取代 SQL 吗?我们测试了 19 个顶级大语言模型的 SQL 编写能力来找出答案。
我们使用 19 个流行的大语言模型外加 1 个人,编写用于过滤和聚合一个 2 亿行数据集的分析 SQL 查询。结果就是完成了 LLM SQL 生成基准测试[1]的第一个版本。
如果你正在寻找最佳的生成 SQL 查询的大预言模型,那这个基准测试将会有所帮助。
使用一组受 ClickHouse® 维护者列表[2]启发的 50 个分析问题,我们测量每个模型编写准确且高效 SQL 的能力。我们通过成功率、精确度、效率、查询延迟和其他指标进行基准测试,并将结果与经验丰富的人类工程师生成的查询进行比较。要了解大语言模型如何在基于文本的 SQL 结果之外,为丰富的交互式分析体验提供支持,请查看我们《关于构建分析生成式 UI 的指南》[3]。
该数据集包含 2 亿行公共 GitHub 事件数据(来自 GH Archive 样本[4]),托管在 Tinybird[5](一款托管 ClickHouse 的工具)中,使我们能够交互式地运行所有查询,并大规模测量性能。完整的结果将 在此[6]公开。
我们为什么这样做?
Tinybird 正使 LLM 成为产品体验的核心部分。这意味着我们的用户直接受到模型生成的 SQL 质量的影响,包括正确性和性能。
我们建立这个基准是为了:
持续评估模型在真实、混乱数据场景中的表现。
在模型演进过程中捕获回归或静默失败。
理解准确率、延迟和成本之间的权衡。
指导我们如何提示、后处理或选择生产中的模型。
本质上,我们确保大语言模型在实际世界中确实能用于 SQL 生成。
剧透:目前还不理想……
数据集:GitHub Archive
GitHub Archive,一个包含自 2011 年以来所有 GitHub 事件的公共数据集,作为基准测试的源数据。该存档包含数十亿行数据,追踪了星标、分支、问题、拉取请求、评论、推送等。
我们为基准测试随机抽取了原始数据集的 2 亿行子集。这些数据以单个 MergeTree 表的形式[7]存储在 Tinybird 中,其架构如下。它包含枚举、低基数字符串、时间戳和数组等混合类型的数据。
分析 SQL 的问题
每个大语言模型必须根据 50 个关于公共 GitHub 活动的自然语言提示或问题生成 SQL。你可以在 这里[8]找到所有问题的完整列表。
每个问题的措辞都像自然语言一样:“过去 7 天内按星标排名的前 10 个仓库”,等等。
模型必须:
解析这个问题
编写正确的 SQL(有效语法、正确的列、正确的分组)
在表上运行它并返回准确输出
系统提示
每个模型都收到相同的系统提示。它明确告诉模型该做什么不该做什么,例如:
不允许虚构字段。如果字段不在模式中,查询就是无效的
不要选择所有列。除非明确要求,否则避免使用
SELECT *没有
ORDER BY不允许使用LIMIT
其他指令:
仅返回 SQL,不要解释
性能优化:最小化
rows_read完整的表结构包含在提示中
提供可用字段和兼容函数的完整列表
参与测试的模型
到目前为止,我们已测试了 Anthropic、OpenAI、Google、Meta、DeepSeek 和 Mistral 的 19 个模型,包括:
Claude 3.5 & 3.7 Sonnet (Anthropic)
Gemini 1.5 Pro (Google)
GPT-4 Turbo (2024-03) (OpenAI)
LLaMA 3 70B / 8B (Meta)
Mistral 7B & Mixtral1
DeepSeek Chat v3(付费版和免费版)
随着时间的推移,我们计划扩大测试范围,并在新模型由主要供应商发布时加入其中。
我们如何衡量性能?
每个查询都使用这些指标进行评分:
指标 | 含义 |
|---|---|
有效查询率 | 返回有效、可执行 SQL 代码的问题百分比 |
首次尝试成功率 | 首次尝试返回有效查询的问题百分比 |
执行时间 | SQL 执行延迟(毫秒) |
LLM 生成时间 | 大模型生成响应所需时间 |
尝试次数 | 生成有效 SQL 需要多少次重试 |
读取行数 | 每执行一次查询读取多少行 |
读取的数据 | 每条查询执行读取的数据量(以字节为单位) |
查询长度 | SQL 的 token 数量 |
除了原始性能指标外,我们还计算了一些附加分数,以更好地捕捉整体质量。这些分数将正确性和效率结合为可解释的值:
指标 | 含义 |
|---|---|
效率分数 | 一个 LLM 在生成查询方面的表现如何,基于查询生成的速度、所需的尝试次数以及查询执行的速度?(更多内容见下文) |
精确度得分 | 该查询的输出与人类等效输出有多接近?(更多内容见下文) |
得分 | (效率 + 精确度)/ 2 |
这些衍生指标有助于突出权衡:有些模型精确但低效,另一些则快速但容易出错。
衡量输出效率
在要求大语言模型生成分析 SQL 查询时,一个重要的考虑因素是它们在计算资源上的效率。在临时分析和商业智能场景中,这种影响可能微不足道,并且值得在人力资源时间上做出权衡。
然而,在实时、高并发场景中,查询可能每天运行数千或数百万次,效率低下的查询会累积,并可能消耗大量计算资源,带来巨大成本或用户体验下降。
我们计算一个效率分数,该分数考虑了大语言模型生成查询的效率(重试次数、总生成时间、失败次数)以及查询本身在读取行/数据、每行字节数和延迟方面的效率。
这里[9]展示了我们用于计算 rawEfficiencyScore 的代码(该分数随后被标准化到 0-100 的刻度上,100 代表最高效率)。根据我们的基准测试结果,似乎大语言模型通常能生成准确或高效的查询,但较少生成既准确又高效的查询,尤其是在提示复杂性增加时。
这其中部分原因可能可以用系统提示来解释:我们要求大语言模型尽量减少读取的数据量,这可能影响它们在查询需要变得不那么高效才能达到准确的情况下,是否愿意继续优化查询(尽管我们尚未用不同的提示变体来验证这一假设)。
有些大语言模型似乎以牺牲效率为代价来生成准确的 SQL:要么它们会多次尝试,要么生成的查询读取的数据量比人类编写的查询多得多。例如,OpenAI 的 o4-mini-high 成功为所有 50 个提示生成了功能性的 SQL,但其平均读取的数据量比人类多 32%,是所有模型中最高的。
在其他情况下,大语言模型编写高效的查询,但它们没有回答提示。例如,Meta 的 llama-4-scout 似乎在数据处理方面编写了高效的查询,但在许多情况下,它要么未能生成有效的查询,要么编写了一个功能性的查询,但没有解决提示。也就是说,这些查询是“不精确的”……
衡量输出精确度
在比较大语言模型生成的查询与人类编写的查询时,挑战不仅在于检查查询是否能运行 —— 更在于它是否能返回语义上相似的结果。但由于 SQL 结果的结构和顺序可能不同(例如,列名或位置并不重要),传统的精确匹配会失效,必须采用更启发式的方法。
相反,我们将查询结果视为行集,并使用基于集合和数值的距离度量来衡量它们的相似性:
杰卡德距离(0 = 相同,1 = 完全不重叠):将结果视为唯一的行集进行比较,忽略顺序和列名。
数值 RMSE(0 = 相同,1 = 最大差异):比较匹配行中的数值,考虑相对误差。
F 分数(越高越好):平衡两个结果集之间的精确度和召回率,以捕捉部分正确性。
你可以在基准测试存储库的 result-validator.ts[10]中看到这是如何计算的。
为确保公平性,我们在所有问题和模型上应用相同的指标。我们不针对个案调整阈值或更换距离函数。这避免了挑选样本,使得模型比较具有意义,即使不同查询的数值距离尺度有所不同。
每个查询返回一组布尔值( matches 、 exactMatches 、 numericMatches )和原始距离值。这些值使我们能够跟踪硬正确性(通过/失败)以及结果偏离的程度 —— 这在查询 “几乎正确” 时很有用。
你会注意到,即使是在精确度方面得分最高的模型,Anthropic 的 claude-3.7-sonnet[11],在我们的精确度启发式度量中,平均得分仍然略高于 56 分。
关键结果
许多模型在正确性上表现不错,但错失了巨大的优化机会。另一些模型虽然经常在正确性上出错,但仍然能生成技术效率高的查询。以下是基准测试中最相关的要点,按模型组分解并按性能排名。
Claude 在准确性上占据主导地位(但在速度上不是)
Claude 3.7 总体排名第一。Claude 3.5 排名第三。
两者在第一次尝试中都能得到 100%有效查询和超过 90%的生成率。
平均精确度相对较高(约 52-56),但并非完美。
生成时间更慢(约 3.2 秒)。
读取的行数:~3700 万–4000 万 — 不算最差,但也不算特别高效。
OpenAI 的 o3/o4 全面优秀的模型
o3-mini 排名第二。o4-mini 紧随其后,排名第六。
100% 有效的查询,~88–92%的首次尝试成功率。
精确度~51–55。
延迟低于 700 毫秒。
读取行数:~4900 万–5200 万 — 具有竞争力,但并非顶尖。
LLaMA 3 失败,LLaMA 4 恢复
LLaMA 3.3 70B 垫底(第 19 名)。
仅 66% 的有效查询。
52% 的初次尝试成功率较低。
精确度:35.56。
LLaMA 4 Maverick (#9)和 Scout (#11) 表现更好。
有效性:100%和 96%。
Scout 总体读取的数据最少:129MB/查询。
精确度:44–48。
Gemini 因延迟而退出
Gemini 2.5 Pro Preview (#12) 准确率(91.8%)但速度慢:每生成一个样本需要 40 秒。
Flash 版本(2.0 和 2.5)具有更快的响应时间。
但精确度较低(约 40-42),整体得分较弱。
人类仍然在效率方面领先
人类 SQL 读取约 3100 万行,每个查询只需 760MB。
没有模型在原始成本或选择性上接近。
大多数模型读取 1.5 倍至 2 倍更多的行。
文章要点
大语言模型擅长编写 SQL,但要得到正确的 SQL(即能够回答提示的 SQL)又是另一回事。即使一个查询运行并返回了数据,也不意味着它在语义上正确、高效或值得信赖。在评估大语言模型的 SQL 能力时,这些都是在实际分析中至关重要的边缘情况 ——而人类判断仍然占上风。
正确性并非非黑即白
仅仅因为查询能运行并不意味着它是正确的。模型常常生成能返回结果的查询,但逻辑存在缺陷:错误的过滤器、错误的分组或使用错误的时戳。这些错误很隐蔽,如果不了解意图很难发现。
示例:对于“与错误或功能相关的 10 个标签”,人类通常使用arrayJoin(labels)进行筛选,并用ILIKE '%bug%' OR ILIKE '%feature%'进行过滤。大多数模型要么跳过arrayJoin,要么精确匹配标签,从而遗漏了 bugfix 或 feature-request 等条目。
整个基准测试手动验证输出结果。高成功率并不总是意味着语义正确的结果。
SQL 仍然是一项技能
自然语言往往不足以表达精确的数据逻辑。像 “最活跃的仓库” 或 “顶级贡献者” 这样的提示很模糊。我们统计问题、PR、评论还是星标?在什么时间范围内?使用什么过滤器?
大语言模型可以猜测(而且通常猜得很好),但如果你自己不能写或读查询,你就无法验证其正确性。即使有最好的 SQL 能力的大语言模型,SQL 仍然是一项必要的技能。理解大语言模型在 SQL 能力上的局限性至关重要。
大语言模型难以处理上下文
即使模型能够访问完整架构,它们仍会遗漏上下文细节。例如,问题编号并非全局唯一,而repo_name既包含组织也包含项目。如果你不完全理解 GitHub 的事件模型,这些信息很容易被误解。
有些大语言模型会将所有事件归纳到共享字段下,或在不同上下文中重复使用标识符。这会导致错误的连接、虚增的计数或无声的聚合错误。
实时分析 ≠ Text2SQL
这些问题是不同的。像 Tinybird 这样的实时系统优先考虑负载下的性能:延迟、吞吐量和列式效率。大语言模型通常会忽略这一点,除非有明确指示。
示例:对于“按问题评论数排名的前 10 个仓库”,人类会过滤event_type = 'IssueCommentEvent'并按仓库进行聚合。一些模型尝试使用 IssuesEvent 并依赖静态评论字段,该字段仅反映当前问题状态(而不是完整的事件流)。另一些模型则通过不合理的连接操作使问题复杂化。
这些查询不仅效率低下,在任何基于时间或流式处理的环境中都是错误的。
LLMs 猜测,人类保留
当不确定时,大语言模型往往会过度处理:读取更多行、选择更多字段或放宽筛选条件。这会消耗更多资源并扭曲结果。
示例:与其筛选 4-5 种特定的事件类型,模型可能会统计所有事件中的贡献者,包括分支、发布甚至 Gist。这会导致输出结果杂乱且膨胀。
人类往往更为保守。即使他们低估了数量,逻辑也更容易验证和控制。
数据暴露是一种权衡
最佳模型结果出现在模型能够访问真实数据时。但这样做会暴露私人或敏感信息,尤其是在使用用户级别或权限绑定的字段进行查询时。
目前还没有真正的解决方案。这仍然是一个活跃的研究领域,也是希望安全使用大语言模型的多租户平台日益增长的关注点。
一些指导
如果你正在使用大语言模型构建分析工具,以下是一些建议:
注入模式感知:提供数据库结构、表关系和数据类型作为上下文,帮助大语言模型生成准确查询并理解数据限制。
实现查询检查和验证:在执行前添加后处理来检查生成的 SQL 是否存在语法错误、性能问题或安全漏洞。
根据上下文平衡因低效、不准确和生成时间过长而导致的惩罚:你的用例决定了查询效率、准确性或生成速度哪个更重要。
通过执行结果建立反馈循环:捕获查询结果和错误消息,在初始尝试失败时迭代改进生成的查询。
链式专用模型:使用不同的大语言模型处理分析流程的不同部分(查询生成、可视化建议、结果解释)。
使用结构化输出格式添加护栏:使用标记标签控制响应结构,确保下游流程的一致性解析。
实施自我评估检查:在展示结果之前,让模型根据定义标准评估其分析输出。
创建上下文感知的提示模板:开发包含用户历史记录、查询模式和特定领域约束的标准模板。
参考资料
[1]
LLM-测试基准:https://llm-benchmark.tinybird.live/
[2]ClickHouse 维护者列表:https://ghe.clickhouse.tech/
[3]关于构建分析生成式 UI 的指南》:https://www.tinybird.co/blog-posts/generative-analytics-ui-with-tinybird-and-thesys
[4]GH Archive 样本:https://www.gharchive.org/
[5]Tinybird:https://tinybird.co/
[6]Tinybird 测试结果:https://llm-benchmark.tinybird.live/
[7]GH Archive Schema:https://github.com/tinybirdco/llm-benchmark/blob/main/src/tinybird/datasources/github_events.datasource
[8]问题列表:https://github.com/tinybirdco/llm-benchmark/tree/main/src/tinybird/endpoints
[9]计算代码:https://github.com/tinybirdco/llm-benchmark/blob/main/src/src/lib/eval.ts
[10]计算方式:https://github.com/tinybirdco/llm-benchmark/blob/main/src/benchmark/result-validator.ts
[11]claude-3.7-sonnet:https://llm-benchmark.tinybird.live/models/claude-3.7-sonnet
如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发朋友圈,
可以到各大平台找我,
微信公众号:@bisal的个人杂货铺
腾讯云开发者社区:@bisal的个人杂货铺
头条号:@bisal的个人杂货铺
CSDN:@bisal
ITPub:@bisal
墨天轮:@bisal
51CTO:@bisal
小红书:@bisal
抖音:@bisal
近期更新的文章:
《NBA季后赛的对阵》
《RAG通俗易懂的理解》
《系统"向后兼容"的重要性》
《英超第三十一轮》
《政务、地产、新零售、短剧出海的数据库选型指南 & 平凯数据库云服务发布 (福州站)》
近期Vlog:
《千岛湖》
《Skyline Luge》
《新疆之行(红山体育馆 - 国际大巴扎 - 红山公园 - 天山天池)》
《新疆之行(天马浴河 - 哈因塞 - 那拉提 - 依提根塞)》
《新疆之行(六星街 - 伊昭公路 - 夏塔)》
热文鉴赏:
《揭开"仿宋"和"仿宋_GB2312"的神秘面纱》
《Linux的"aarch"是多了个"a"?》
《中国队“自己的”世界杯》
《你不知道的C罗-Siu庆祝动作》
《大阪环球影城避坑指南和功略》
《推荐一篇Oracle RAC Cache Fusion的经典论文》
《"红警"游戏开源代码带给我们的震撼》
文章分类和索引:
《公众号2000篇文章分类和索引》
