基于Calcite制作分库分表中间件(方案1)

 

分库分表中间件的查询引擎是特别重要的一个功能,在一些Java生态的数据库中,使用Calcite作为查询器,在这个系列,我将为大家介绍如何在分库分表中间件中使用Calcite.

我会描述流程,而不在乎细节.细节会在后面的系列补充.

 

RBO第一阶段-下推分片条件谓词

 

使用下推LogicalFilter的规则与

org.apache.calcite.rel.rules.FilterTableScanRule
org.apache.calcite.rel.rules.ProjectTableScanRule

规则把Filter下沉到LogicTableScan之上

FilterTableScanRule和ProjectTableScanRule会把LogicalTable转化成

org.apache.calcite.interpreter.Bindables.BindableTableScan

如果不使用BindableTableScan,自己编写规则应用下面描述的重写器完成替换物理表也可以

 

RBO 第二阶段-关系表达式重写

然后进入RBO使用自己编写的关系表达式重写器,

org.apache.calcite.interpreter.Bindables.BindableTableScan#filters

进行谓词条件分析,得出逻辑表对应的一个或者多个物理表,把不符合谓词条件的物理表去掉,然后使用LogicalUnion把多个物理表LogicalTableScan以及合拼成一个新的关系表达式替换BindableTableScan

结果类似

LogicalUnion(LogicalProject(LogicalFilter(LogicalTableScan))....)

 

RBO 第三阶段-上拉UnionAll

RBO第二阶段上拉UnionAll

该阶段是为了下推更多关系表达式比如count,limit,join到UnionAll之下

 

 

RBO第四阶段-生成分片执行SQL

生成分片执行的SQL

 

上面提到LogicalTableScan已经被替换成物理表,所以物理表是带有分片信息的,此时我们只需要检查那些有多个输入的非叶子关系表达式(因为叶子都是LogicalTableScan),他们的输入节点是否都是同一个分片,如果是,则记录下来,自向上求出靠近根部的关系表达式是哪些,然后它们转换为SQL即可,并且使用临时表结合其他接口

 

org.apache.calcite.schema.TransientTable

 

org.apache.calcite.schema.QueryableTable
org.apache.calcite.schema.FilterableTable
org.apache.calcite.schema.ScannableTable
org.apache.calcite.schema.ProjectableFilterableTable

构造临时表保存关系表达式(在执行器执行的时候变成SQL就可以)或者保存对应的SQL

 

生成执行器

直接使用解释器运行或者使用CBO生成执行器即可

org.apache.calcite.interpreter.InterpretableConvention//解释器
org.apache.calcite.adapter.enumerable.EnumerableConvention//代码生成器

 

调优

1.调整下推谓词的规则

2.调整上拉UnionAll的规则

3.调整生成SQL的规则

4.提供统计元数据给CBO优化

5.完善谓词分析算法

6.Gather算子替换UnionAll算子,并完成并行执行器

7.可以试试上拉UnionAll再下推谓词的方案