一条 SQL 的查询优化之旅【下】

您所在的位置:网站首页 F-cost怎么读 一条 SQL 的查询优化之旅【下】

一条 SQL 的查询优化之旅【下】

2023-04-13 11:36| 来源: 网络整理| 查看: 265

上一篇文章我们讲解了 Apache Calcite 架构设计及 SQL 优化器概述,这篇文章我们将接着介绍 Apache Calcite 组件的关键原理。

三、Calcite SQL 解析和元数据验证关键原理解析 3.1 Calcite SQL 解析关键原理

当一条 SQL 语句到达引擎,首先通过的是 SQL 解析器,SQL 解析器将用户输入的 SQL 语句转换为一棵抽象语法树,同时在这个过程里,它还会对SQL进行词法和语法校验,如果输入的 SQL 有词法或语法问题,会在这个阶段收到错误提示。

在 Calcite 中,一棵抽象语法树通常用SqlNode来表示。以下面这条 SQL 为例:

这条SQL在经过 Calcite 解析后,形成的 AST 抽象语法树如下:

图中的每一个节点都是一个 SqlNode,SqlNode作为抽象语法树的顶级抽象,相互关联组成了一颗大的抽象语法树。

Calcite 支持通过两种方式进行 SQL 解析:即基于 Java CC(Java Compiler Compiler)的 SQL 解析以及基于 Anltr 的 SQL 解析。Calcite 默认基于 Java CC 来做 SQL 解析:Calcite 能够基于Parser.jj 文件,使用 Java CC 技术,动态生成 SQL 解析实现类(XXXParserImpl),Calcite 本身内置有一个 Parser.jj 文件,如果我们需要自定义 SQL 语法的时候,我们也可以使用 FMPP 技术,自定义 ftl和 config.fmpp 文件的内容,来控制最终需要生成的Parser.jj 的内容,从而实现自定义 SQL 语法。

config.fmpp 主要定义 SQL 语法中的关键字、外部引入的类(如自定义的 SqlNode)、以及一些 SQL 解析方法定义等等,具体的实现一般会在 ftl 文件中。以 Apahce Flink 项目举例,组成其 SQL 解析器模块的主要文件如下:

3.2 Calcite SQL 校验和关系代数转换流程 3.2.1 Calcite SQL 元数据校验

上文我们提到:SQL 解析后会形成一棵 SqlNode 的抽象语法树,下一步我们需要对这棵树进行元数据验证,以校验SQL的合法性。这里需要注意,经过元数据验证之后的SqlNode,其本质还是一棵SqlNode 树,之后依然需要经过 SqlNode 到RelNode关系代数的转换,才会形成一棵由RelNode组成的关系代数节点树。

在 Calcite 元数据验证阶段,其主要验证三个点:

对 SQL 语句中的 Table Schema 进行校验,如 Table 存不存在,Column 存不存在

对 SQL 语句中函数进行校验,如函数是否存在

针对数据类型的校验,如函数中的参数数据类型和函数定义是否匹配

Calcite 中元数据验证源码的核心方法入口为:SqlValidatorImpl.validate(),SqlValidatorImpl的使用,需要配合SqlOperatorTable,SqlValidatorCatalogReader,RelDataTypeFactory三个类使用。SqlValidatorImpl 的初始化构造器的源码如下:

初始化 SqlValidatorImpl 需要传入三类参数:

SqlOperatorTable-生产函数和 SQL Operator 的工厂,为SqlValidatorImpl 提供函数、SQL 操作符(比如 >,=,



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3