☰
SOAR 体系架构深度解析:语法解析、集成环境、优化建议与重写逻辑
2026/9/25 11:05:07 网站建设 项目流程
  • 开发工具
  • 数据库

【免费下载链接】soar

SQL Optimizer And Rewriter

项目地址:https://gitcode.com/gh_mirrors/so/soar
点击查看免费下载

SOAR(SQL Optimizer And Rewriter)是一款由小米数据库团队开发维护的 SQL 优化与改写自动化工具,其整体架构由语法解析器、集成环境、优化建议、重写逻辑、工具集五大模块组成。本文以官方架构文档 doc/structure.md 为主线,结合仓库源码逐一拆解每个模块的设计思路与底层实现,读者可以借此掌握 SOAR 从 SQL 输入到优化建议产出的完整调用链路,以及如何为二次开发或深度使用定位到对应代码位置。

五大模块总览

SOAR 的架构图如下,整个系统呈现一条清晰的流水线:SQL 先经过语法解析与检查,再在集成环境中完成环境准备,随后由优化建议模块产出评审结论,必要时由重写逻辑产出等价改写后的 SQL,最后由工具集负责输出格式化与展示。

围绕这条流水线,doc/structure.md 将 SOAR 拆解为五大模块:

模块核心职责对应源码目录
语法解析器将 SQL 解析为抽象语法树并做语法检查ast/、advisor/rules.go 中 ERR 规则
集成环境区分线上/测试环境,提供安全执行与元数据支撑database/、common/config.go
优化建议启发式规则、索引优化、EXPLAIN 解读三类建议advisor/heuristic.go、advisor/index.go、advisor/explainer.go
重写逻辑数十种常见场景下的 SQL 等价转写ast/rewrite.go
工具集markdown 转 HTML、SQL 格式化等辅助能力common/markdown.go、common/tricks.go

语法解析和语法检查:三套解析器的可插拔组合

一条 SQL 从文件、标准输入或命令行参数等形式传递给 SOAR 后,首先进入语法解析器。在解析器的选型上,SOAR 采用了"松散、可插拔"的集成方案,而不是自行维护一套庞大的语法解析库,其演进过程分为三步:

  1. Vitess 语法解析库(首选):项目最初选用 Vitess 的sqlparser作为主解析库。从源码可见,SOAR 在构造评审对象Query4Audit时,先用sqlparser.Parse(sql)生成 Vitess 抽象语法树,但"vitess 语法解析不上报,以 tidb parser 为主"(见 advisor/rules.go);
  2. TiDB 语法解析器(补充):随着需求增加,部分复杂 SQL 用 Vitess 实现较为吃力,因此引入 TiDB(pingcap/parser)的语法解析器作为补充。ast.TiParse()会先通过removeIncompatibleWords()预处理 pingcap/parser 不支持的语法,例如剔除ON UPDATE CASCADE、把CREATE TEMPORARY TABLE改写为CREATE TABLE等(见 ast/tidb.go);
  3. MySQL 执行返回结果(方言盲区兜底):两套解析器仍存在盲区,因此 SOAR 又引入 MySQL 真实执行返回结果,作为多版本 SQL 方言的补充,例如对 Vitess 语法错误(ERR.000)、执行错误(ERR.001)与 EXPLAIN 错误(ERR.002)的识别都依赖这一路输入。

在 advisor/rules.go 的规则代号注释中,ERR被明确标注为"特指 MySQL 执行返回的报错信息",这印证了三路解析输入在错误处理层面的分工。

集成环境:线上环境与测试环境的双环境设计

集成环境区分线上环境与测试环境,用于解决不同场景下的 SQL 优化需求:

  • 已有表结构的优化场景:从线上环境导出表结构和足够采样数据到测试环境,即可在测试环境放心执行各种高危操作而不用担心数据损坏;
  • 全新数据库的验证场景:只需验证数据字典中是否存在优化可能,用户甚至不需要知道线上环境在哪,试错成本极低。

这两个环境在配置结构体Configuration中对应OnlineDSN与TestDSN两个数据源配置,另有一系列开关控制行为(见 common/config.go):

配置项含义
online-dsn/test-dsn线上/测试环境的数据库连接(addr、schema、user、password、disable)
allow-online-as-test允许 Online 环境同时当作 Test 环境使用
disable-version-check禁用环境检测(不建议开启,可能导致语句执行异常)
drop-test-temporary是否清理 Test 环境产生的临时库表
cleanup-test-database清理程序异常退出时残余的测试数据库
sampling/sampling-condition数据采样开关与采样条件
profiling/trace/explain测试环境执行的 Profiling、Trace 与 Explain 开关

从 advisor/index.go 的NewAdvisor()可以看出,索引建议正是同时依赖env.VirtualEnv(测试环境)与database.Connector(线上环境)两个句柄:DDL 语句会先把库表元数据登记进测试环境;遇到USE语句则切换测试环境当前库。关于双环境更完整的组合场景说明,见 集成环境。

优化建议:三类建议的合并输出

目前 SOAR 可提供三类优化建议:基于启发式规则(经验)的建议、基于索引优化算法的建议、以及基于 EXPLAIN 信息的解读。

启发式规则建议

启发式规则的元数据结构由规则代号、危险等级、规则摘要、规则解释、SQL 示例、建议位置、规则函数七部分组成,其定义如下(见 advisor/rules.go):

// Rule 评审规则元数据结构 type Rule struct { Item string `json:"Item"` // 规则代号 Severity string `json:"Severity"` // 危险等级:L[0-8], 数字越大表示级别越高 Summary string `json:"Summary"` // 规则摘要 Content string `json:"Content"` // 规则解释 Case string `json:"Case"` // SQL示例 Position int `json:"Position"` // 建议所处SQL字符位置,默认0表示全局建议 Func func(*Query4Audit) Rule `json:"-"` // 函数名 }

每一条 SQL 经过语法解析后会经过数百个启发式规则逐一检查,命中的规则保存在heuristicSuggest变量中传递下去,与其他优化建议合并输出。规则的代号具有明确的缩写语义,例如:

  • ALI(Alias):ALI.001建议显式使用 AS 关键字声明别名,ALI.002不建议给通配符*设置别名(L8 高危),ALI.003提示别名不要与表或列同名;
  • ARG(Argument):ARG.001不建议使用前项通配符查找(like '%foo'),ARG.002提示没有通配符的 LIKE 等价于等值查询;
  • ALT(Alter):ALT.001提醒修改表默认字符集不会改已有字段字符集,ALT.002建议同一张表多条 ALTER 合并,ALT.003/ALT.004将删除列、删除主外键标记为高危操作;
  • COL、IDX、JOI、SEC、SUB等分别对应列、索引、连接、安全、子查询等维度,完整清单见 advisor/rules.go。

所有启发式规则实现的函数集中在 advisor/heuristic.go(共 4160 行),规则列表保存在 advisor/rules.go(共 1610 行)中。规则函数与规则代号在InitHeuristicRules()中通过 map 绑定,例如RuleImplicitAlias对应ALI.001、RulePrefixLike对应ARG.001。运行时可以通过soar -list-heuristic-rules打印全部规则,用soar -ignore-rules "ALI.001,IDX.*"忽略指定规则(见 doc/cheatsheet.md)。

索引优化

索引优化模块的挑战在于把 DBA 沉淀的经验转化为覆盖全面、逻辑可推导的算法。SOAR 参考了大量前人著作、论文与博客(知识来源汇总在 鸣谢 章节),核心算法依据《Relational Database Index Design and the Optimizers》一书提出的三星索引理论(Three-Star Index):第一颗星选取 WHERE 等值谓词列作为索引首列;第二颗星加入 ORDER BY 列并保持原有顺序;第三颗星将查询涉及的剩余列加入索引以形成覆盖索引(见 advisor/index.go)。

在实现层面,IndexAdvisor结构体(见 advisor/index.go)收集了whereEQ(等值条件列)、whereINEQ(非等值条件列)、groupBy、orderBy、joinCond(跨层级 JOIN 条件)等信息;IndexInfo则输出一条完整索引建议,包含索引名、库名、表名、DDL 语句与列详情。索引优化的详细算法描述见 索引优化。

EXPLAIN 解读

EXPLAIN 信息对新手而言记忆负担极重:SOAR 仅在 EXPLAIN 信息注解一项就编写了约 200 行代码,按平均行长 120 计算,相当于为 DBA 节省了不下 2 万字的记忆量。解读逻辑集中在 advisor/explainer.go,实现上采用"按维度检查、按表聚合建议"的方式:

  • checkExplainSelectType():按配置的ExplainWarnSelectType匹配SelectType并给出建议;
  • checkExplainAccessType():按配置的ExplainWarnAccessType匹配访问类型(如全表扫描),输出Scalability提示;
  • checkExplainRef():检查Ref列为 NULL 的访问路径;
  • 对 JSON 格式的 EXPLAIN 结果,会先通过database.ConvertExplainJSON2Row()转成行格式统一处理。

所有 EXPLAIN 类建议以EXP.XXX作为规则代号。完整的解读逻辑见 EXPLAIN 信息解读。

重写逻辑:从"给建议"到"帮改写"

早期 SOAR 的功能停留在建议层面,初级用户看到建议也不一定会改写。为降低 SQL 优化成本,SOAR 进一步实现了自动 SQL 重写,提供几十种常见场景下的 SQL 等价转写。重写规则定义在 ast/rewrite.go 中,每个规则包含名称、描述、错误示范(Original)、正确示范(Suggest)与改写函数,且规则是有序的,先后顺序不能乱。已内置的改写规则包括:

规则名作用
dml2select/reg2select将 DELETE 等更新请求转换为只读 SELECT,便于执行 EXPLAIN
star2columns为SELECT *补全表的列信息
insertcolumns为INSERT补全列信息
having将 HAVING 中的查询条件改写进 WHERE
orderbynull为不需要排序的 GROUP BY 添加ORDER BY NULL
unionall用UNION ALL替代UNION提高查询效率
or2in/or2union同列 OR 转 IN、不同列 OR 转 UNION
dmlorderby删除 DML 更新操作中无意义的 ORDER BY
sub2join/join2sub子查询与 JOIN 的相互转换
distinctstar删除对带主键表无意义的DISTINCT *
standardSQL 标准化,如关键字转小写

规则之间的依赖顺序同样在代码中体现,例如注释明确"把所有跟 or 相关的重写完之后才进行 or 转 union 的重写"。重写功能的完整逻辑见 重写逻辑,运行时可结合 doc/cheatsheet.md 中-rewrite-rules配置项启用或关闭指定规则。

工具集:优化之外的辅助能力

除了 SQL 优化和改写,SOAR 还提供一系列辅助小工具,方便用户使用并美化输出展现形式:

  • Markdown 转 HTML 工具:将 markdown 报告转为带样式的 HTML,支持report-type、report-css、report-javascript、report-title等配置项控制输出风格(见 common/config.go 与 common/markdown.go);
  • SQL 格式化输出工具:支持 SQL 压缩与美化,相关实现见 ast/pretty.go 与 ast/rewrite.go 中的格式化逻辑;
  • 其他实用命令:-list-heuristic-rules打印全部启发式规则、-list-report-types打印支持的报告格式、-print-config打印配置等。

所有小工具的具体用法都能在 常用命令 中找到,例如最基本的用法:

echo "select title from sakila.film" | ./soar -log-output=soar.log

小结:一条 SQL 在 SOAR 中的完整旅程

回顾整个架构,SOAR 的处理流水线可以概括为:SQL 输入 → 三路语法解析(Vitess + TiDB + MySQL 执行结果)→ 集成环境准备(线上/测试 DSN)→ 三类优化建议合并输出(启发式规则 + 索引算法 + EXPLAIN 解读)→ 等价重写 → 工具集美化输出。五大模块各司其职,同时保持了"松散、可插拔"的设计风格——解析器不自己维护,规则以 map 形式注册、以heuristicSuggest传递合并,重写规则有序联动。对于想深入定制规则的开发者,advisor/heuristic.go 与 ast/rewrite.go 是最佳切入点;而对于想快速上手的使用者,常用命令 与 配置文件 文档则提供了完整的操作指引。

  • 开发工具
  • 数据库

【免费下载链接】soar

SQL Optimizer And Rewriter

项目地址:https://gitcode.com/gh_mirrors/so/soar
点击查看免费下载
上一篇:从命令行到一键搞定:Deepin Boot Maker如何让Linux启动盘制作变得如此简单
下一篇:Deepin Boot Maker:免费开源启动盘制作工具的终极完整指南(2025最新版)

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询