Compiling Semantic Plans into Dialect SQL: An 11-Step Engineering Pipeline—— 数据基础设施技术札记 · 2026摘要随着大语言模型驱动的数据消费场景兴起业界对「让 LLM 直接生成 SQL」的工程局限性逐步形成共识幻觉率、口径偏差、权限越界、性能踩踏四类故障在生产环境难以根治。本文系统阐述「LLM 输出语义计划 编译器编译」这一替代范式给出一条由 11 个确定性步骤构成的工程化编译流水线并对其中三个核心算法Binder、Join Resolver、Policy Rewrite给出复杂度分析与伪代码实现。我们进一步讨论方言适配中的 AST 后处理、字段级权限的编译期重写、以及成本守护Cost Guard与物化视图路由的判定准则。在 Spider 与 BIRD 两个公开基准之外私有 schema 集合上的实验显示该方案在「无 hallucination 字段权限合规 编译延时 30 ms」三个维度上同时满足生产要求与 LLM 直接生成 SQL 的范式存在数量级差距。本文不预设任何具体产品实现意在为构建企业级语义层Semantic Layer的工程师提供一个完整的设计参考。关键词语义层 · Text-to-SQL · 查询编译 · 关系代数 · 字段级访问控制 · 物化视图选择 · 方言适配1. 引言在 ChatGPT 公开发布之后的两年里「Text-to-SQL」成为数据领域热度最高的工程命题之一。它的逻辑路径直观且诱人把用户自然语言交给一个足够强的大语言模型LLM让模型直接生成 SQL再把 SQL 交给数据仓库执行。Spider [1] 与 BIRD [2] 这两个公开基准的不断攻顶加上 GPT-4o 与 Claude 系列模型在合成基准上接近八成的 execution accuracy使得「LLM 端到端生成 SQL」似乎成为不可阻挡的趋势。然而把这一范式部署到企业生产环境的工程团队会很快发现基准上的高分并不等于生产可用。Spider 和 BIRD 测试的是「在已知 schema 与公开数据上生成 SQL」的能力而企业的真实约束远不止此——字段语义在不同源系统中存在同义异名、口径在不同事业部之间存在差异、字段级访问控制必须严格满足合规、以及查询所触发的成本必须在数据仓库的承受范围内。这些约束在 LLM 直接生成 SQL 的范式中没有承载点模型既看不见企业的指标定义也无法在生成 SQL 的同时做权限决策与成本估算。本文论述的范式与上述路径正交。我们主张把「自然语言 → SQL」分解为「自然语言 → 语义计划Semantic Plan→ SQL」两段其中第二段由一个确定性的编译器Compiler完成。这样的拆分把不确定性约束在第一段由 LLM 完成、可重试可回滚并把企业的所有知识schema、口径、权限、成本模型、方言封装进第二段由编译器持有、版本化、可审计。本文的贡献是i给出一条由 11 个确定性步骤组成的语义查询编译流水线并描述每一步的输入、输出、不变式与时间复杂度ii对其中三个非平凡步骤——Binder、Join Resolver、Policy Rewrite——给出完整伪代码与复杂度分析iii在公开基准与私有 schema 集合上比较该方案与 LLM 直接生成 SQL、LLM RAG、LLM Fine-tuning 三种代表性方案。2. 抽象层级与相关工作2.1 四层抽象Figure 1. 语义查询编译的四层抽象层级从用户意图L1到物理 SQLL4如 Figure 1 所示本文采用的抽象层级如下L1 · 自然语言用户的口语化表达存在歧义、省略与隐含上下文。这一层完全由 LLM 处理。L2 · 语义计划Semantic Plan用一个固定 JSON Schema 描述「要什么指标、按什么维度、什么时间范围、用什么过滤器」。语义计划不引用物理表名、字段名或 SQL 语法。这是 LLM 输出的终点也是 Compiler 输入的起点。L3 · 关系代数 AST经过 Binder、Join Resolver、Policy Rewrite 等操作后形成的内部表示。这一层使用扩展关系代数含投影、选择、连接、聚合、上下卷动与具体数据库方言无关。L4 · 物理 SQL经过方言适配后的具体 SQL 字符串可以直接交给数据仓库执行。这种四层抽象与编译器领域的中间表示IR思想一脉相承但与传统数据库系统的查询编译有几个关键差异第一输入不是 SQL 而是 JSON第二编译器需要持有「指标定义」与「字段权限」这类元数据而非仅仅是 schema第三方言适配是「输出多种 SQL」而非「优化执行计划」。2.2 相关工作本文工作可置于三条工程脉络之中。第一条脉络是 Apache Calcite [3] 所代表的查询规划器。Calcite 提供了一套关系代数 IR 与基于规则的优化器被 Apache Flink、Apache Hive、Apache Druid 等多个项目作为内部查询编译框架。Calcite 解决的是「SQL → 优化后的执行计划」的问题与本文「JSON → SQL」的问题前后衔接。本文方案在 AST 构建阶段步骤 S9借鉴了 Calcite 的 RexNode/RelNode 设计但因为输入是 JSON 而非 SQL省去了 SQL 解析阶段。第二条脉络是以 dbt MetricFlow [4]、Cube.dev [5]、AtScale [6]、Looker LookML [7] 为代表的语义层项目。这些工具都试图把指标定义与口径维护下沉到独立的语义层但工程实现差异显著dbt MetricFlow 强调用 YAML 配置 metric并通过 SQL 模板拼接生成查询Cube 提供一个基于 JavaScript DSL 的语义模型与 REST APIAtScale 以 OLAP cube 为核心抽象Looker LookML 则把语义模型与 BI 前端深度耦合。本文方案与这些工具相比的特异点在于第一把「字段级权限」作为编译器一等公民在 AST 阶段做树重写而不依赖外部 BI 工具或行级安全策略第二编译器对外暴露的是「语义计划 JSON」而不是 SQL 或 REST 接口便于被 LLM 通过 Function Calling 直接调用。第三条脉络是近期围绕 LLM 与数据库结合的研究DAIL-SQL [8] 与 DIN-SQL [9] 探索了把 schema 检索与多步分解结合的 prompt 工程C3-SQL [10] 提出了一个清晰、校准、一致的 prompt 范式而 MAC-SQL [11] 则提出了多 agent 协作。这些工作仍在「LLM 直接生成 SQL」的范式内打补丁与本文方案存在范式差异。我们认为这些方法可与本文方案互补让一个轻量级的 LLM 仅生成语义计划 JSON再由 Compiler 负责所有其余工作。3. 编译流水线设计Figure 2. 语义查询编译的 11 步流水线及各步时间复杂度我们把语义查询编译分解为 11 个确定性步骤如 Figure 2 所示。每一步对输入做一次单调变换要么细化 AST要么补充元数据不引入任何随机性。下面对每一步给出定义与复杂度。3.1 S1 — ValidatorValidator 负责对输入的语义计划 JSON 做 schema 校验必填字段、字段类型、值域范围、时间范围合法性。这一步是纯结构检查时间复杂度 O(|P|)其中 |P| 是 plan 的字段数。Validator 的存在意义不仅是防御 LLM 输出的格式错误更重要的是把「不合法的输入」与「合法但语义错误的输入」明确分开——前者直接拒绝后者交给后续步骤的语义检查。3.2 S2 — BinderBinder 把语义计划中的指标与维度引用绑定到注册表Registry中的 Object业务对象与 Property属性。这是把「逻辑符号」与「企业知识」对齐的关键步骤。Binder 的时间复杂度是 O(|M| · O_lookup(R))其中 |M| 是 plan 中的 metric/dimension 数O_lookup 是注册表的查找复杂度。当注册表使用哈希表实现时 O_lookup O(1)故 Binder 整体为 O(|M|)。Figure 3. 语义计划绑定算法Binder Algorithm的伪代码Figure 3 给出了 Binder 的完整伪代码。值得注意的是第 5 行与第 10 行的两次异常抛出UnboundMetric 与 UnknownProp 是绑定阶段的两类典型错误必须在 Binder 即拒绝而不能让错误漏到后续步骤。第 13 行的 verifyTypeCompat 是一个常被忽略的细节——当 plan 中的 filter 对一个 INTEGER 类型字段做字符串比较时要么在编译期拒绝要么显式做类型转换绝不能让数据仓库在运行时抛错。▎工程见解Binder 是「语义计划」与「企业知识」的契约接口。把 Binder 设计为「严格拒绝未知字段」而不是「宽容地猜测最相似字段」是工程上的关键决策——后者会把「LLM 幻觉表名」的问题原封不动地复制到编译器内部。3.3 S3 — Join Resolver在多对象multi-object查询中Compiler 需要决定如何 Join 这些对象。Join Resolver 把 Object 视为节点、把声明过的 Relationship 视为有向边构建一张关系图然后在这张图上求解一棵覆盖所有目标对象的最短连接树Steiner Tree。在企业场景下关系图节点数通常不超过数百边数为数千BFS / DFS 的时间复杂度 O(|V| |E|) 完全可接受。Figure 4. Join Resolver 在对象关系图上的最短连接路径解析Figure 4 展示了一个典型的关系图。当用户的查询同时引用 Customer、Order、Product 时Resolver 选择路径 Customer → Order → Product 而不是 Customer → Region → Store → Order → Product因为前者经过更少的中间节点hops且每跳的 cardinality 已通过 Relationship 元数据预先标定。需要强调的是Join Resolver 不应「自主发现」未声明的关系。如果一对 Object 之间没有显式声明 RelationshipResolver 必须报错而不是尝试通过字段名相似性去猜测——这与 Binder 的「严格拒绝未知字段」是同一个工程哲学。3.4 S4-S5 — Filter Push 与 AggregationFilter Push 把 plan 中的 filter 条件按照「最早过滤」原则下推到 AST 中最接近源表的位置等价于关系代数中的 σ(π(R)) → π(σ(R)) 重写。时间分区裁剪是其中最值得关注的一类当 filter 触及分区键如 dt 2026-04-01时Compiler 必须确保下推后的 AST 节点保留这一信息以便方言适配阶段生成 PARTITION 子句。Aggregation 步骤按用户提供的 dimension 列表组装 GROUP BY同时对 metric 应用各自定义的聚合函数SUM / AVG / COUNT DISTINCT / 自定义 UDAF。这一步的关键约束是「类型可加性」sum(amount) 是可加的avg(price) 不可加但 sum(price * quantity) / sum(quantity) 可加。Compiler 必须根据 metric 的定义元数据自动决定是否需要展开为可加形式。3.5 S6 — Policy RewriteFigure 5. 字段级权限重写在 AST 上的树重写规则示意蓝色节点为新增Policy Rewrite 是本文方案与传统语义层最重要的区别之一。如 Figure 5 所示给定用户角色 role(u) 与字段权限规则集合 ΠCompiler 对 AST 进行如下重写对于 AST 中每个投影节点 π_f若 role(u) ∉ Π.access(f)则将其重写为π_{CASE(role, f, ⊥)}即用 CASE WHEN 表达式包裹使越权用户得到 NULL 而非真实值同时在 σ 子树中合取一个行级过滤org_id ∈ Π.rowAccess(u)。这一重写的时间复杂度是 O(|Π| · |F|)其中 |Π| 是用户角色匹配的策略条数|F| 是 AST 中投影字段数。对一个典型的中等复杂度查询|F| ≈ 20|Π| ≈ 50重写耗时在 0.5 ms 以内。▎工程见解字段权限决策在编译期完成 vs 运行期完成是一个关键工程取舍。编译期决策本文方案的优势是 SQL 已带权限、数据仓库零额外开销、可静态审计劣势是策略变更需要重新编译。运行期决策行级安全策略 / View / 中间件代理的优势是策略变更立即生效劣势是每次查询都付额外开销且权限逻辑分散难以审计。在 OLAP 场景查询频次高、策略变更频次低下编译期决策几乎总是正确选择——这是一个被广泛忽视的取舍。3.6 S7 — Materialization RoutingMV Routing 决定当前查询是否能够利用一张已物化的视图。这是一个变体 MV-Selection 问题在已选定 MV 集合的前提下做匹配可建模为给定查询Q的AST与候选MV集合M {m_1, m_2, ..., m_k}查找子集S ⊆ M使得Q ⊑ rewrite(S)并最小化cost(rewrite(S))。完整 MV-Selection 是 NP-hard [12]。在工程上我们做两个简化a只考虑「单 MV 命中」即 |S| ≤ 1b对 MV 做指纹fingerprint索引把匹配复杂度降到 O(|M| · log|M|)。在我们的实测中这两个简化让 95% 的查询在 1 ms 内完成 MV 路由判定而损失的「多 MV 组合命中」机会不到 3%。▎工程见解在工程实践中「物化视图选择」常被神化为一个 NP-hard 难题从而成为团队不优化此模块的借口。但 80/20 法则在这里成立90% 的工程问题用「Top-K 频次抽样 单 MV 命中」就能解决只有当物化预算极为紧张时才需要完整的 MV-Selection 算法。3.7 S8 — Cost GuardCost Guard 在 AST 完成构建后做一次成本估算估算扫描行数、Shuffle 数据量、CPU 时间。当估算值超过预设阈值时例如「单查询扫描超过 10 亿行」Cost Guard 选择拒绝查询、自动降级如自动加 TOP 100、或要求用户确认。成本估算本身可以做得很精细基于 histogram sample但在我们的实践中一个粗糙的「按表大小线性外推」估算就足以拦截 99% 的问题查询。Cost Guard 的真正价值不是「精确估算」而是「在 SQL 执行前能拦截」——这与传统数据库的「query timeout」相比是一个数量级的工程优势。3.8 S9-S11 — AST Build, Dialect Adapt, ExplainAST Build 把内部 IR 转为方言无关的 SQL AST参考 Calcite 的 RelNode 设计。Dialect Adapt 做方言相关的后处理日期函数DATE_ADD vs DATEADD vs date INTERVAL、字符串函数CONCAT vs ||、限定语法TOP vs LIMIT、引号约定 vs vs 等。Explain 生成一个包含「AST 摘要 Policy 应用 MV 命中 估算成本」的 explain 对象并写入审计日志。Explain 是本方案对企业级合规的关键支撑任何一次查询用户都能问「这个数是怎么算出来的」并得到一个完整的因果链。这相比「LLM 直接生成 SQL」的范式而言是一个不可逆的工程优势。4. 实验评估Figure 6. 实验对比编译延时与 Text-to-SQL 准确率4.1 编译延时Figure 6(a) 给出了本文方案与 LLM 直接生成 SQL 的延时对比。横轴是「查询复杂度」用 # metrics × # joins 度量纵轴是「编译延时 SQL 生成延时」log 坐标。三条曲线分别是本文方案无 MV 缓存、本文方案含 MV 缓存、LLM 直接生成 SQLGPT-4o。可以看到本文方案的延时随查询复杂度近似线性增长在最复杂的查询上仍保持在 100 ms而 LLM 直接生成 SQL 的延时受模型 inference 延时主导几乎是常数 ≈ 350 ms。在简单查询上LLM 方案反而比 Compiler 方案慢一个数量级——这是 inference 延时的不可消除特性。4.2 Text-to-SQL 准确率Figure 6(b) 给出了在 Spider、BIRD、私有 schema 集合上的 execution accuracy 对比。私有 schema 集合包含 200 个查询覆盖一个虚拟企业的 schema30 张事实表 80 张维度表每个查询都附带正确答案。可以看到LLM 直接生成 SQL 在公开 benchmark 上的准确率随着 LLM 能力提升而提升62% → 78%但在私有 schema 上下降到 48%。RAG 与 Fine-tuning 在公开 benchmark 上有改进但在私有 schema 上仍未突破 65%。本文方案在所有 benchmark 上的准确率都是 100%在去掉 LLM 生成语义计划的「意图理解」失败之后——这是一个本质性的差异在「意图正确理解」之后Compiler 的生成不存在概率性失败。需要强调的是本文方案的「准确率」不是与 LLM 方案的「准确率」可直接对比的指标——前者衡量的是「确定性」后者衡量的是「正确率」。但在企业场景下「确定性」是「准确率」的上限——一个不能保证确定性的方案无论概率多高都无法满足审计要求。4.3 字段权限合规性我们构造了 50 个「越权查询」测试用例用户角色不包含某字段访问权限但在自然语言中请求该字段。LLM 直接生成 SQL 的方案完全无法处理这类用例除非在 prompt 中手工注入权限信息。本文方案在 Policy Rewrite 步骤自动拦截全部 50 个用例返回脱敏值或拒绝查询。5. 讨论与局限5.1 LLM 仅负责意图理解足够吗本方案的隐含假设是LLM 能够稳定地把自然语言映射为正确的语义计划 JSON。当 schema 与指标定义足够完备时这个映射相对简单因为目标是结构化 JSON 而非 SQL。但当用户的自然语言本身存在歧义时如「最近的销售」既可以指「最近 7 天」也可以指「上个季度」LLM 仍可能选错。对策有二第一在语义计划 Schema 中允许「partial plan」表达如 time_range null由 Compiler 拒绝并要求用户澄清第二让 LLM 在歧义场景下输出多个候选 plan由 UI 让用户选择。这两种策略都比「LLM 直接生成 SQL 然后跑错」要更可控。5.2 何时不该用本方案本方案在两种场景下不适合aschema 演化极快如分析师每天创建新表此时 Registry 维护成本过高b查询完全开放如数据科学家做探索性分析此时把所有可能的查询都建模为 Object/Metric 不现实。对这两类场景更好的选择是「为分析师提供受控的 Notebook SQL 编辑器」而非端到端的语义层。5.3 与多源联邦查询的协同本方案默认查询发生在一个数据仓库内。当查询涉及跨多个异构源OLTP OLAP 文档库时需要在 S9AST Build之后插入一个 Federation 步骤将 AST 切分为多个子计划分别下发到不同源执行后做最终合并。这部分超出本文范围但其工程接口是清晰的。5.4 与流式语义查询的协同本方案默认查询是批式的snapshot semantics。对流式语义查询如「过去 5 分钟的实时 GMV」需要在 S5Aggregation阶段引入 windowing 与 watermark 概念。Apache Flink 的语义已为此提供成熟范式可直接借鉴。6. 结论与未来工作本文系统阐述了「LLM 输出语义计划 Compiler 编译」这一范式给出由 11 个确定性步骤构成的工程化流水线。在 Spider、BIRD、私有 schema 集合上的实验表明该方案在「无 hallucination 字段权限合规 编译延时 30 ms」三个维度上同时满足生产要求与 LLM 直接生成 SQL 的范式存在数量级差距。未来工作有三个方向。第一在 Compiler 中加入「自学习成本模型」根据执行历史动态修正 Cost Guard 的阈值估算。第二扩展语义计划 Schema 以支持更复杂的查询语义如对话上下文、隐式 join、模糊 group by。第三把 Compiler 本身作为一个「可观察、可干预」的组件暴露——让数据团队能够在不重新构建系统的前提下对编译策略做白盒调试。▎工程见解终局判断「LLM 直接生成 SQL」这一范式在企业生产环境中将逐渐淡出因为它既无法保证确定性也无法承载企业级的权限与口径约束。取而代之的是「LLM 负责理解意图、Compiler 负责生成 SQL」的明确分工——这与软件工程发展史上「人写汇编 → 编译器生成汇编 → 人写高级语言」的演化路径一致。参考文献[1]Yu T, Zhang R, Yang K, et al. Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task. EMNLP 2018.[2]Li J, Hui B, Qu G, et al. Can LLM Already Serve as A Database Interface? A BIg Bench for Large-Scale Database Grounded Text-to-SQLs. NeurIPS 2023.[3]Begoli E, Camacho-Rodríguez J, Hyde J, et al. Apache Calcite: A Foundational Framework for Optimized Query Processing Over Heterogeneous Data Sources. SIGMOD 2018.[4]dbt Labs. MetricFlow: A Semantic Layer for Modern Data Stacks. https://docs.getdbt.com/docs/build/about-metricflow[5]Cube.dev. Headless BI for Building Data Applications. https://cube.dev/[6]AtScale. The Semantic Layer for the Modern Data Stack. https://www.atscale.com/[7]Looker. LookML Reference. https://cloud.google.com/looker/docs/lookml-quick-reference[8]Gao D, Wang H, Li Y, et al. Text-to-SQL Empowered by Large Language Models: A Benchmark Evaluation. VLDB 2024.[9]Pourreza M, Rafiei D. DIN-SQL: Decomposed In-Context Learning of Text-to-SQL with Self-Correction. NeurIPS 2023.[10]Dong X, Zhang C, Ge Y, et al. C3: Zero-shot Text-to-SQL with ChatGPT. arXiv 2023.[11]Wang B, Ren C, Yang J, et al. MAC-SQL: A Multi-Agent Collaborative Framework for Text-to-SQL. arXiv 2024.[12]Mami I, Bellahsene Z. A Survey of View Selection Methods. ACM SIGMOD Record 2012.关于我们