Calcite 源码编译与运行
一、概述
1)简介
Calcite是一个数据库查询优化器。
2)使用方式
1.将Calcite作为独立的服务,向下对接异构数据源,上层应用则使用Calcite原生的JDBC接口,利用SQL语句进行请求和响应。
2.将Calcite进行拆分,作为一个嵌入式的组件存在于查询引擎当中。
例如:Hive、Flink
3)架构
Calcite的各个组件可以分为4种类型
1.查询优化器(Query Optimizer)
是整个Calcite的核心,它会对上游产生的逻辑查询计划进行优化,生成最终的执行计划。
在优化过程中,查询优化器基于优化模型,对SQL关系代数算子树进行优化,查询优化器会根据不同的优化模型来选择不同的优化策略。
在Calcite中,查询优化器提供了两种优化模型:
一种是根据经验来进行查询优化的启发式模型(Heuristic Model),它一般会根据预先设定的优化规则,对查询计划进行优化,例如谓词下推、常量折叠等确定会对查询带来性能提升的策略都属于启发式模型的范畴。
另一种是基于代价的优化模型——火山优化模型(Valcano Model),火山模型不仅会考虑到预先设定的优化规则,还会综合考量数据集的统计信息(数据行数、某个字段的基数、最小值、最大值等)以及当前服务器的状态(CPU性能、内存占用率、网络情况等),最终将上层的逻辑计划转换成更符合当前场景的物理查询计划。
2.操作表达式(Operator Expression)、元数据提供器(Metadata Provider)、插件化优化规则(Pluggable Rule)
其中操作表达式会对操作表达式进行适配,内部包含输入的原始计划、中间结果以及最终输出的计划
元数据提供器会对元数据进行适配
插件化优化规则会对优化规则进行适配
所有的适配器都可以根据具体的场景进行扩展
3.其它流程性的组件
例如负责接收JDBC请求的JDBC服务器(JDBC Server)
负责解析SQL语法的SQL解析器(SQL Parser)
负责校验SQL语法的SQL校验器(SQL Validator)
以及负责构建表达式的表达式构建器(Expression Builder)
4.最外层的数据处理系统(Data Processing System)和数据源(Data Source)
用户可以根据自己的需要,挂载不同的数据执行引擎。
二、源码编译与运行
1)从 githup clone 源码
git clone https://github.com/apache/calcite.git
2)编译源码
1.修改 calcite/gradle.properties
对 systemProp.org.gradle.internal.publish.checksums.insecure=true 增加 # 号注释
#systemProp.org.gradle.internal.publish.checksums.insecure=true
2.执行 gradle 的 build 操作
三、使用 Calcite 内置的 SQLLine 操作 model.json 中的数据
进入项目目录,启动内置的 SQLLine
cd */calcite/example/csv
./sqlline
注意:执行以下命令时,带 !的无需加 ;号
1、基础操作
1)利用SQLLine来连接数据库的命令
!connect jdbc:calcite:model=src/test/resources/model.json admin admin
2查看所有表的元数据信息
!tables
+-----------+-------------+------------+--------------+---------+----------+------------+-----------+---------------------------+----------------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS | TYPE_CAT | TYPE_SCHEM | TYPE_NAME | SELF_REFERENCING_COL_NAME | REF_GENERATION |
+-----------+-------------+------------+--------------+---------+----------+------------+-----------+---------------------------+----------------+
| | SALES | DEPTS | TABLE | | | | | | |
| | SALES | EMPS | TABLE | | | | | | |
| | SALES | SDEPTS | TABLE | | | | | | |
| | metadata | COLUMNS | SYSTEM TABLE | | | | | | |
| | metadata | TABLES | SYSTEM TABLE | | | | | | |
+-----------+-------------+------------+--------------+---------+----------+------------+-----------+---------------------------+----------------+
3)查看某张表里面所有的字段元数据信息
!columns DEPTS
+-----------+-------------+------------+-------------+-----------+-----------+-------------+---------------+----------------+----------------+----------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | COLUMN_NAME | DATA_TYPE | TYPE_NAME | COLUMN_SIZE | BUFFER_LENGTH | DECIMAL_DIGITS | NUM_PREC_RADIX | NULLABLE |
+-----------+-------------+------------+-------------+-----------+-----------+-------------+---------------+----------------+----------------+----------+
| | SALES | DEPTS | DEPTNO | 4 | INTEGER | -1 | null | null | 10 | 1 |
| | SALES | DEPTS | NAME | 12 | VARCHAR | -1 | null | null | 10 | 1 |
+-----------+-------------+------------+-------------+-----------+-----------+-------------+---------------+----------------+----------------+----------+
2、查询操作
1)查询Calcite中的数据
SELECT * FROM DEPTS;
+--------+-----------+
| DEPTNO | NAME |
+--------+-----------+
| 10 | Sales |
| 20 | Marketing |
| 30 | Accounts |
+--------+-----------+
3 rows selected (1.598 seconds)
2)使用聚合操作和连接操作来查询和处理Calcite中的数据
0: jdbc:calcite:model=src/test/resources/mode> SELECT d.name, COUNT(*)
. . . . . . . . . . . . . . . . . . semicolon> FROM emps AS e JOIN depts AS d ON
. . . . . . . . . . . . . . . . . . semicolon> e.deptno = d.deptno GROUP BY d.name;
+-----------+--------+
| NAME | EXPR$1 |
+-----------+--------+
| Sales | 1 |
| Marketing | 2 |
+-----------+--------+
2 rows selected (0.667 seconds)
3)通过函数来完成对数据的构建和运算
0: jdbc:calcite:model=src/test/resources/mode> VALUES CHAR_LENGTH('Hello, ' || 'world!');
+--------+
| EXPR$0 |
+--------+
| 13 |
+--------+
1 row selected (0.15 seconds)
4)查看连接信息
0: jdbc:calcite:model=src/test/resources/mode> !list
1 active connection:
#0 open jdbc:calcite:model=src/test/resources/model.json
5)使用"!all"命令对所有数据库连接执行相同操作
!all DELETE FROM COMPANY
6)在SQLLine中读取外部配置文件信息
!properties test.properties
7)查看当前所有数据源驱动信息的操作
0: jdbc:calcite:model=src/test/resources/mode> !scan
scan complete in 15ms
3 driver classes found
Compliant Version Driver Class
yes 0.0 org.apache.calcite.avatica.remote.Driver
yes 1.36 org.apache.calcite.jdbc.Driver
yes 2.7 org.hsqldb.jdbc.JDBCDriver
8)使用SQL语句来对底层数据源进行查询的操作
SELECT * FROM DEPTS;
9)在SQLLine中执行一个SQL文件中的所有SQL语句的操作
!run example.sql
3、事务操作
1)使用"!autocommit"命令将自动提交事务的功能关闭,后面事务需要手动提交才能生效
!autocommit off
2)删除数据
delete from DEPTS;
3)回滚删除的数据
!rollback
4、输出操作
设置输出格式
1)在SQLLine中将输出格式设置为表格格式
!outputformat table
2)在SQLLine中将输出格式设置为CSV文件格式
!outputformat csv
在SQLLine中查看当前执行的进程的情况
!procedures %JDBC%
在SQLLine中将查询结果输出到指定文件当中
使用“!record”命令指定输出路径,将之后的数据输出到该文件当中
!record /Users/hhx/Desktop/mysession.out
使用“!record”命令停止数据的输出
!record
5、在SQLLine中将当前的配置信息进行保存
!save
退出连接
!q