这是我参与「第四届青训营 」笔记创作活动的的第1天
大数据体系
大数据体系和SQL
SQL的优势:方便简单,使用性广,支持多种接口.......
目标:通过SQL处理所有大数据
SQL处理流程
Parser
输入一个字符串文本,输出一个语法树
-
String -> AST ( abstract syntax tree )
- 词法分析:拆分字符串,得到关键词(select,from...)、数值常量、字符串常量、运算符号等token
- 语法分析:将token 组成AST node,最终得到一个ASR
- 实现:递归下降(ClickHouse),Flex和 Bison (PostgreSQL),JavaCC (Flink) , Antlr (Presto,Spark)
Analyzer 和 Logical Plan
Analyzer
输入抽象语法树输出逻辑计划
- 检查并绑定Database(数据库),Table(表名), Column(列名)等元信息
- SQL的合法性检查,比min/max/avg的输入是数值
包括数据类型,关键字等检查
- AST -> Logical Plan
Logical Plan
- 逻辑地描述SQL对应的分步骤计算操作
- 计算操作∶算子(operator)
SQL算子可以理解为SQL语句执行过程中各个步骤的具体动作。在left-deep tree中一个结点就是一个算子
拓展内容-------算子的分类
- From 算子
From 算子是 SQL 语句中最基本的算子,用于定位 SQL 语句的操作对象,主要出现在 SELECT 语句中,但 DDL 语句和 DML 语句中则隐式地包含了 From 算子。
- Scan 算子
Scan 算子是用于扫描操作的算子,作用于表和视图。Scan 算子根据扫描的执行方式可以分为 TableScan 算子和 IndexScan 算子,分别执行顺序扫描和基于索引扫描。
- Filter 算子
顾名思义,Filter 算子是条件过滤算子,用于在 SQL 语句中根据一定的条件过程表或视图中的数据。Filter 算子中至少包含一个过滤条件,且 Filter 算子中可以包含非常复杂的过滤条件。
- Join 算子
Join 算子是用于完成连接操作的所有算子的统称,Join 算子本身包含了连接条件。在具体的 SQL 语句中,Join 算子可以隐式表达,也可以表达为 join … on … 形式。
- 分组算子
分组算子是完成分组操作的算子,最常用的是 Group 算子和 Having 算子,还包括 Cube 算子、Rollup 算子等。
Group 算子是完成分组操作的核心算子,而 Having 算子则提供了分组筛选条件。
- 排序算子
Order 算子是 SQL 语句中用于执行排序操作的算子。排序操作是 SQL 语句中的常见操作,也是重要操作,而排序算子的具体实现,在不同的数据库中经常不同,同一种数据库中也会提供多种算法用于完成排序。
- 投影算子
投影是 SELECT 语句中的必要组成部分,表达了 SELECT 语句的输出内容的结构。投影算子可以有多种形式,甚至投影列本身就是一个独立的 SQL 语句(子查询),最常见的表现形式是表或视图中的列,此外还可以表现为 Scalar 算子、Aggregation 算子或 Window 算子。
Scalar 算子是完成标量运算的算子,都涉及到标量函数运算。
Aggregation 算子是聚合运算算子,包括 COUNT、MAX/MIN、SUM/AVG 等,通常结合分组算子出现。
Window 算子是窗口操作算子,以窗口函数形式出现。Window 算子是个复合结构,可以进一步细分为窗口函数算子、Over 算子、Partition 算子和Order 算子。
- Value 算子
Value 算子是完成非投影部分的求值运算的算子,一般表现为标量函数,通常出现于其它多种算子的各种条件表达式中,比如出现在 Filter 算子或 Join 算子中完成过滤条件表达式或连接条件表达式的求值运算。
- Top N 算子
Top N 算子是完成限定操作的算子的统称,限定操作指的是基于结果集并在结果集上完成某种行为的操作,Top N算子的最典型的应用场景是分页。
Top N 算子具体可以表达为 Top、Limit、Offset、RowNum 等关键字。
- Exchange 算子
Exchange 算子是 SQL 语句执行过程中在各执行步骤之内或之间完成数据交换的算子,在并行场景或分布式场景中起作用。Exchange 算子是由数据库引擎调度的算子,其动作不能由人工参与。
查询优化
- SQL是一种声明式语言,用户只描述做什么,没有告诉数据库怎么做
- 目标:找到一个正确且执行代价最小的物理执行计划
- 查询优化器是数据库的大脑,最复杂的模块,很多相关问题都是NP的
- 一般 SQL越复杂,Join的表越多,数据量越大,查询优化的意义就越大,因为不同执行方式的性能差别可能有成百上千倍
Physical Plan 和Executor
Plan Frafment:
执行计划子树
- 目标:最小化网络数据传输
- 利用上数据的物理分布(数据亲和性)
在分布式系统上,一个表的数据可能分布在多个结点上,在读结点数据时,尽量读本地数据,减少远程读取的频率
- 增加Shuffle算子
一边发送一边接收
Executor
- 单机并行:cache , pipeline,SIMD
- 多机并行:一个 fragment 对应多个实例
小结:
- One SQL rules big data all
- SQL需要依次经过Parser ,Analyzer , Optimizer 和Executor的处理
- 查询优化器是数据库的大脑,在大数据场景下对查询性能至关重要
- 查询优化器需要感知数据分布,充分利用数据的亲和性
- 查询优化器按照最小化网络数据传输的目标把逻辑计划拆分成多个物理计划片段