点击标题下「蓝色微信名」可快速关注技术社群的这篇文章《人机协奏曲当 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 ArchiveGitHub 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 Mixtral1DeepSeek 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 完全不重叠将结果视为唯一的行集进行比较忽略顺序和列名。数值 RMSE0 相同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的个人杂货铺CSDNbisalITPubbisal墨天轮bisal51CTObisal小红书bisal抖音bisal近期更新的文章《NBA季后赛的对阵》《RAG通俗易懂的理解》《系统向后兼容的重要性》《英超第三十一轮》《政务、地产、新零售、短剧出海的数据库选型指南 平凯数据库云服务发布 福州站》近期Vlog《千岛湖》《Skyline Luge》《新疆之行红山体育馆 - 国际大巴扎 - 红山公园 - 天山天池》《新疆之行天马浴河 - 哈因塞 - 那拉提 - 依提根塞》《新疆之行六星街 - 伊昭公路 - 夏塔》热文鉴赏《揭开仿宋和仿宋_GB2312的神秘面纱》《Linux的aarch是多了个a》《中国队“自己的”世界杯》《你不知道的C罗-Siu庆祝动作》《大阪环球影城避坑指南和功略》《推荐一篇Oracle RAC Cache Fusion的经典论文》《红警游戏开源代码带给我们的震撼》文章分类和索引《公众号2000篇文章分类和索引》