SQL 优化的过程能够分为逻辑优化和物理优化两个局部。逻辑优化次要是基于规定的优化,简称 RBO(Rule-Based Optimization)。物理优化会为逻辑查问打算中的算子抉择某个具体的实现,须要用到一些统计信息,决定哪一种形式代价最低,所以是基于代价的优化 CBO(Cost-Based Optimization)。
优化器是开务数据库中的一个外围的模块,开务数据库应用优化器来实现对 SQL 语句优化并失去最优的逻辑打算,开务数据库里的优化器分为 RBO 和 CBO 两个阶段。
RBO 是基于规定的优化,这些规定背地的原理是关系代数的等价变换,其中典型的规定包含:列剪裁,谓词下推等。RBO 将内置的规定作为优化的根底,同时这些规定是硬编码在开务数据库的代码中的,RBO 会依据这些规定从指标 SQL 诸多可能的代数转换中抉择一条来作为逻辑打算。
开务数据库的 RBO 优化器采纳了 Optgen 语言编写,它提供了一种直观的语法来定义、匹配和替换指标表达式树中的节点。优化器规定的编写便是基于这种语言,应用 Optgen 语言能够很容易实现 RBO 规定。
开务数据库的 RBO 规定实现如下图所示,①被称为匹配模式,②被称为替换模式,优化器规定是某表达式满足①模式,而后转化为②模式的表达式。
①的匹配模式又分为三局部,第一局部中括号内是规定的名称,在 Opt 文件编译时会作为规定的标识,第二局部是第二行左小括号后位规定作用域,在开务数据库内有明确的类型划分。编写规定时要分明这条规定是针对哪种类型表达式产生作用,第三局部是剩下的规定局部,是规定的匹配条件。
模式①匹配条件是等值表达式,左孩子不是变量,右孩子是变量。这里的 NormalizeEq 是名称,Eq 是规定类型,针对等值表达式。模式②示意新构建一个等值表达式,只是与原表达式相比,左右孩子调换。示例:1=a => a=1
开务数据库内置了上百种 RBO 规定,反对大量的 SQL 语句的代数优化,包含传统的列裁剪、最大最小打消、投影打消、谓词下推等等,也包含一些简单的 Join 等下推操作。TryDecorrelateGroupBy,这个规定的 OptGen 规定形容如下:
[TryDecorrelateGroupBy, Normalize](InnerJoin | InnerJoinApply $left:* $right:* & (HasOuterCols $right) & (GroupBy | DistinctOn $input:* $aggregations:* $groupingPrivate:* ) & (IsUnorderedGrouping $groupingPrivate) $on:* $private:*)=>(Select ((OpName $right) (InnerJoinApply $newLeft:(EnsureKey $left) $input [] $private ) (AppendAggCols $aggregations ConstAgg (NonKeyCols $newLeft) ) (AddColsToGrouping $groupingPrivate (KeyCols $newLeft)) ) $on)
TryDecorrelateGroupBy 次要作用在 InnerJoin | InnerJoinApply 操作中,它将 Join“下推”到 GroupBy 运算符中,以尝试持续“开掘”以找到并打消不必要的相关性。最终的心愿是触发 DecorrelateJoin 规定,将 JoinApply 操作符转换为非 Apply Join 操作符。
SELECT left.x, left.y, input.*FROM leftINNER JOIN LATERAL ( SELECT COUNT(*) FROM input WHERE input.x = left.x GROUP BY c) AS inputON left.y = 10=>SELECT CONST_AGG(left.x), CONST_AGG(left.y), COUNT(*)FROM left WITH ORDINALITYINNER JOIN LATERAL ( SELECT * FROM input WHERE input.x = left.x) AS inputON TrueGROUP BY input.c, left.ordinalityHAVING left.y = 10
开务数据库采纳了 Optgen 语言作为 RBO 规定的编写语言,通过下面的例子能够看出,依照既定模式增加欠缺 RBO 规定非常便捷,通过编译能够将规定嵌入到零碎 RBO 规定框架中;后续会有更深刻的对于 RBO 应用框架与大家分享,敬请期待!