在数据库开发实践中,很多工程师都遇到过这样一个“诡异”的场景:明明在SQL中明确写了LEFT JOIN,但执行计划打出来却显示优化器自动将其转换成了INNER JOIN甚至更高效的HASH JOIN。这种“越俎代庖”的行为,到底是优化器的bug,还是有意为之的高明设计?近日,人大金仓自主研发的KingbaseES(简称KES)数据库向外界公开了其优化器核心设计思路,揭开了这一“悄悄改掉”操作背后的技术逻辑。
为什么优化器“胆敢”修改用户语义?
传统观念认为,LEFT JOIN代表左表全部保留、右表不匹配时补NULL的强语义,任何改写都可能破坏业务逻辑。然而,KES优化器团队指出:优化器的所有改写行为,均建立在“语义等价”的严格数学证明之上。换言之,只有当优化器通过规则推导确认改写后的SQL与原语句在所有可能的数据分布下结果完全一致时,才会实施转换。
例如,用户写:
SELECT * FROM A LEFT JOIN B ON A.id = B.id WHERE B.value > 10;
此时WHERE条件中显式要求B表列非空,等价于强制B表必须有匹配行,LEFT JOIN的外连接特性实际上已被“中和”。优化器自动识别这种模式,将其降级为INNER JOIN,从而减少不必要的空行保留与扫描开销。
KES优化器的三大核心设计思路
1. 基于代价的激进决策模型
KES采用了CBO(Cost-Based Optimizer)引擎,每条SQL在生成执行计划前会枚举多种等价变换路径(包括连接顺序交换、连接类型降级、谓词下推等)。每个路径都会通过统计信息计算CPU、I/O、网络开销,最终选择代价最低的版本。当LEFT JOIN转换为INNER JOIN能带来至少30%的性能提升时,优化器会毫不犹豫地选择后者——前提是代价模型中已内置了语义等价校验器。
2. 静默重写的安全边界
金仓团队坦言,“悄悄改掉”并非不顾用户感受。KES引入了一套可溯源的改写日志系统:当优化器执行任何连接类型转换时,会在优化日志中记录原始SQL、转换规则ID、以及等价性证明的摘要。用户可以通过EXPLAIN (ANALYZE, VERBOSE)查看具体改动,甚至通过SET query_rewrite_enabled = off完全禁止此类改写。这种“默认启用但完全可控”的设计,平衡了性能与透明度的需求。
3. 国产化场景下的特殊优化
针对国内政企用户大量使用Oracle、PostgreSQL迁移的场景,KES优化器专门适配了常见的历史遗留SQL模式。例如,很多老系统为了“保险”滥用LEFT JOIN,实际业务逻辑中并不需要外连接特征。KES通过机器学习辅助的统计分布分析,自动识别出那些“假左连”——即右表实际不存在空值匹配的记录——并对这类SQL实施激进的内连转换,部分场景下查询速度提升了5倍以上。
工程师如何应对“被改掉”的风险?
对于有严格数据一致性要求的金融、医疗系统,金仓建议用户采取以下策略:
- 显式声明意图:若必须保留
LEFT JOIN语义,可在ON条件中加入额外约束(如ON A.id = B.id AND B.value IS NOT NULL),从而阻止优化器降级。 - 使用HINT强制固定:KES支持
/*+ NO_REWRITE */Hint,禁止对该查询块执行任何连接类型优化。 - 开启测试模式:在开发阶段使用
set optimizer_verbose=on,观察执行计划中是否有“LEFT JOIN converted to INNER JOIN”的标注,及时修正逻辑。
结语:让优化器成为懂业务的“智能助手”
从“不敢改”到“敢改且改得对”,国产数据库金仓KES正在用一套严谨的语义等价理论+代价驱动模型,重新定义优化器的角色。正如金仓首席架构师所言:“优化器不是篡改用户的代码,而是通过数学证明帮助用户写出真正高效的SQL。当用户发现自己的LEFT JOIN被改掉时,应该高兴——这说明数据库比你更懂你的数据。”在国产化替代加速的今天,这种从“能用”到“好用”的设计跃迁,正是自主数据库赢得信任的关键所在。