这是我参与「第四届青训营 」笔记创作活动的的第1天
我们都知道,很多大数据计算引擎都支持 SQL 作为更高抽象层次的计算入口,查询优化器是数据库系统必备组件,对于 SQL 作业的执行性能起着至关重要的作用。所以说学习sql优化势在必行;
一、大数据架构体系
从上面这副图中我们可以看出,sql在整个大数据体系架构中占据着至关重要的地位。
二、大数据体系和SQL
2.1 SQL的处理流程
●String -> AST (Abstruct Syntax Tree):
- 词法分析:拆分字符串,得到关键词、数值常量、字符串常量、运算符号等token
- 语法分析:将token组成ASTnode,最终得到一个AST
●实现:递归下降 (ClickHouse),Flex 和 Bison (PostgreSQL),JavaCC (Flink),Antlr (Presto,Spark)
2.2 Analyzer和Logical Plan ● Analyzer:
-
检查并绑定Database, Table, Column等元信息
-
SQL的合法性检查,比如min/max/avg的输入是数值
-
AST -> Logical Plan ● Logical Plan:
-
逻辑地描述SQL对应的分步骤计算操作
-
计算操作:算子( operator )
小结:
- One SQL rules big data all
-
SQL 需要依次经过Parser,Analyzer,Optimizer和Executor的处理
-
查询优化器是数据库的大脑,在大数据场景下对查询性能至关重要
-
查询优化器需要感知数据分布,充分利用数据的亲和性
-
查询优化器按照最小化网络数据传输的目标把逻辑计划拆分成多个物理计划片段
三、常见的sql优化器
3.1 RBO
- 扫描表格中所需要的列,而不是全部
- where的表达式是谓词。谓词尽快过滤数据,减少开销2(条件:join是inter)
- 根据表达式等价关系,过滤条件,推导出一个新的过滤条件
对一个join如果能在查询端提早过滤不必要数据,可减少开销
- min-max的缺点:范围必须很紧密
- in-list:只需要扫描in-list里的数据。缺点:集合个数很多时,in-list也很大
- bloom filter:特性:大小不随集合大小改变,固定大小,给一个数可以判断在不在
3.2 CBO
原始表统计信息
- 表或者分区级别:行数、行平均大小、表在磁盘中占用了多少字节等
- 列级别: min、max、num nulls、num not nulls、num distinct value(NDV)、histogram 等
推导统计信息
-
选择率( selecthwty) :对于某一个过滤条件查询会从表中返回多大比例的数据
-
基数( careinality ) :在查询计划中常指算子需要处理的行数
-
单表扫描:索引扫描(随机I/O) vs 全表扫描(顺序IO)
- 如果查询的数据分布非常不均衡,索引扫描可能不如全表扫描
-
Join的实现: Hash Join Vs. SortMerge Join
-
两表Hash Join :用小表构建哈希表如何识别小表?
-
多表Join :
- 哪种连接顺序是最优的?
- 是否要对每种组合都探索?
-
N个表连接,仅仅是left-deep tree就有差不多N!种连接顺序
- e.g. N= 10->总共3, 628, 800个连接顺序
总结:
- 主流RBO实现-般都有几百条基于经验归纳得到的优化规则
- RBO实现简单,优化速度快
- RBO不保证得到最优的执行计划
- CBO使用代价模型和统计信息估算执行计划的代价
- CBO使用贪心或者动态规划算法寻找最优执行计划
- 大数据场景下CBO对查询性能非常重要