美文网首页
Calcite optimizer

Calcite optimizer

作者: 丹之 | 来源:发表于2018-12-07 15:29 被阅读66次

    代数

    关系代数是方解石的核心。每个查询都表示为关系运算符树。您可以从SQL转换为关系代数,也可以直接构建树。

    规划器规则使用保留语义的数学标识来转换表达式树。例如,如果过滤器未引用其他输入的列,则将过滤器推入内连接的输入是有效的。

    Calcite通过重复将规划器规则应用于关系表达式来优化查询。成本模型指导流程,计划程序引擎生成一个替代表达式,该表达式具有与原始语义相同的语义,但成本较低。

    规划过程是可扩展的。您可以添加自己的关系运算符,计划程序规则,成本模型和统计信息。

    代数建设者永久链接

    构建关系表达式的最简单方法是使用代数构建器 RelBuilder。这是一个例子:

    TableScan
    final FrameworkConfig config;
    final RelBuilder builder = RelBuilder.create(config);
    final RelNode node = builder
      .scan("EMP")
      .build();
    System.out.println(RelOptUtil.toString(node));
    

    代码打印

    LogicalTableScan(table=[[scott, EMP]])
    

    它创建了一个EMP表的扫描; 相当于SQL

    SELECT * FROM scott.EMP;
    

    添加项目永久链接

    现在,让我们添加一个Project,相当于

    SELECT ename, deptno FROM scott.EMP;
    

    我们只是project在调用之前添加对方法的调用 build:

    final RelNode node = builder
      .scan("EMP")
      .project(builder.field("DEPTNO"), builder.field("ENAME"))
      .build();
    System.out.println(RelOptUtil.toString(node));
    

    而输出是

    LogicalProject(DEPTNO=[$7], ENAME=[$1])
      LogicalTableScan(table=[[scott, EMP]])
    

    这两个调用builder.field创建了简单的表达式,返回输入关系表达式中的字段,即scan调用创建的TableScan 。

    方解石已经通过序数将它们转换为字段引用, 7并且1。

    添加过滤器和聚合永久链接

    使用Aggregate和Filter的查询:

    final RelNode node = builder
      .scan("EMP")
      .aggregate(builder.groupKey("DEPTNO"),
          builder.count(false, "C"),
          builder.sum(false, "S", builder.field("SAL")))
      .filter(
          builder.call(SqlStdOperatorTable.GREATER_THAN,
              builder.field("C"),
              builder.literal(10)))
      .build();
    System.out.println(RelOptUtil.toString(node));
    

    等同于SQL

    SELECT deptno, count(*) AS c, sum(sal) AS s
    FROM emp
    GROUP BY deptno
    HAVING count(*) > 10
    

    并生产

    LogicalFilter(condition=[>($1, 10)])
      LogicalAggregate(group=[{7}], C=[COUNT()], S=[SUM($5)])
        LogicalTableScan(table=[[scott, EMP]])
    

    推送和弹出永久链接

    构建器使用堆栈来存储由一步生成的关系表达式,并将其作为输入传递给下一步。这允许生成关系表达式的方法生成构建器。

    大多数情况下,您将使用的唯一堆栈方法是build()获取最后一个关系表达式,即树的根。

    有时堆栈变得如此深入嵌套会让人感到困惑。为了保持正确,您可以从堆栈中删除表达式。例如,我们在这里建立一个浓密的连接:

    .
                   join
                 /      \
            join          join
          /      \      /      \
    CUSTOMERS ORDERS LINE_ITEMS PRODUCTS
    

    我们分三个阶段构建它。存储在变量中间结果 left和right,并用push()把他们回来的时候,是时候创建最终在栈上Join:

    final RelNode left = builder
      .scan("CUSTOMERS")
      .scan("ORDERS")
      .join(JoinRelType.INNER, "ORDER_ID")
      .build();
    
    final RelNode right = builder
      .scan("LINE_ITEMS")
      .scan("PRODUCTS")
      .join(JoinRelType.INNER, "PRODUCT_ID")
      .build();
    
    final RelNode result = builder
      .push(left)
      .push(right)
      .join(JoinRelType.INNER, "ORDER_ID")
      .build();
    

    字段名称和序号永久链接

    您可以按名称或序号引用字段。

    普通是从零开始的。每个运算符都保证其输出字段的顺序。例如,Project返回由每个标量表达式生成的字段。

    保证运算符的字段名称是唯一的,但有时这意味着名称并不完全符合您的预期。例如,当您将EMP加入DEPT时,其中一个输出字段将被称为DEPTNO,另一个将被称为DEPTNO_1。

    一些关系表达式方法可以让您更好地控制字段名称:

    project允许你使用包装表达式alias(expr, fieldName)。它会删除包装器但保留建议的名称(只要它是唯一的)。
    values(String[] fieldNames, Object... values)接受一组字段名称。如果数组的任何元素为null,则构建器将生成唯一名称。
    如果表达式投影输入字段或输入字段的强制转换,它将使用该输入字段的名称。

    一旦分配了唯一的字段名称,名称就是不可变的。如果您有特定RelNode实例,则可以依赖不更改的字段名称。实际上,整个关系表达式是不可变的。
    但是如果关系表达式已经通过了几个重写规则(参见(RelOptRule)),结果表达式的字段名称可能看起来不像原始文件。此时最好通过序数引用字段。

    在构建接受多个输入的关系表达式时,需要构建将其考虑在内的字段引用。在构建连接条件时最常发生这种情况。

    假设您正在EMP上构建一个连接,它有8个字段[EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO]和DEPT,它有3个字段[DEPTNO,DNAME,LOC]。在内部,Calcite将这些字段表示为具有11个字段的组合输入行的偏移:左输入的第一个字段是字段#0(基于0,记住),右输入的第一个字段是字段#8。
    但是通过构建器API,您可以指定哪个输入的字段。到参考“SAL”,内部字段#5,写builder.field(2, 0, "SAL"),builder.field(2, "EMP", "SAL")或builder.field(2, 0, 5)。这意味着“两个输入的输入#0的字段#5”。(为什么需要知道有两个输入?因为它们存储在堆栈中;输入#1位于堆栈顶部,输入#0位于堆栈顶部。如果我们没有告诉构建器是两个输入,它不知道输入#0的深度。)

    类似地,参考“DNAME”,内部字段#9(8 + 1),写入builder.field(2, 1, "DNAME"),builder.field(2, "DEPT", "DNAME")或builder.field(2, 1, 1)。

    API摘要永久链接

    关系运算符永久链接

    参数类型:

    堆栈方法永久链接

    标量表达方法永久链接

    官网:
    http://calcite.apache.org/docs/algebra.html

    相关文章

      网友评论

          本文标题:Calcite optimizer

          本文链接:https://www.haomeiwen.com/subject/yubthqtx.html