SQL查询优化器| 青训营笔记

50 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第1天

1.大数据体系和SQL

1.1大数据体系

      分析引擎:a. 批式分析:Spark、Hive、MR

                       b. 实时分析:Flink

                       c. 交互分析:Presto、ClickHouse、Doris

1.2 SQL的处理流程

      --SQL--àParser--AST--àAnalyzer--Logical Plan--àOptimizer--Physical Plan--àExecutor

1.2.1 Parser

      String -> AST (abstract syntax tree)

词法分析:拆分字符串,得到关键词、数值常量、字符串常量、运算符号等token

语法分析:将token组成 AST node,最终得到一个AST

实现:递归下降(ClickHouse),Flex和Bison (PostgreSQL),JavaCC (Flink),AntIr (Presto, Spark)

1.2.2 Analyzer

a. 检查并绑定Database,Table, Column等元信息

b. SQL的合法性检查,比如min/max/avg的输入是数值

AST -> Logical Plan

1.2.3 Logical Plan

      逻辑地描述SQL对应的分步骤计算操作;计算操作:算子(operator)

1.2.4 查询优化

a. SQL是一种声明式语言,用户只描述做什么,没有告诉数据库怎么做

b. 目标:找到─个正确且执行代价最小的物理执行计划

c. 查询优化器是数据库的大脑,最复杂的模块,很多相关问题都是NP的

d. 一般SQL越复杂,Join的表越多,数据量越大,查询优化的意义就越大

1.2.5 Plan Fragment:执行计划子树

a. 目标:最小化网络数据传输

b. 利用上数据的物理分布(数据亲和性)

c. 增加Shuffle算子

1.2.6 Executor

a. 单机并行:cache,pipeline,SIMD   

b. 多机并行:一个fragment对应几个案例

 

2. 常见的查询优化器

2.1 RBO(Rule-based Optimizer)

a. 根据关系代数等价语义,重写查询

b. 基于启发式规则

c. 会访问表的元信息 (catalog),不会涉及具体的表数据(data)

优化策略:列裁剪、谓词下推、传递闭包、Runtime Filter

2.2 CBO(Cost-based Optimizer)

      使用一个模型估算执行计划的代价,选择代价最小的执行计划

a.      执行计划的代价等于所有算子的执行代价之和

b.     通过 RBO得到(所有)可能的等价执行计划

2.2.1 统计信息类型

a. 原始表统计信息

表或者分区级别:行数、行平均大小、表在磁盘中占用了多少字节等

列级别: min、max、num nulls、num not nulls、num distinct value(NDV)、histogram等

b.     推导统计信息

选择率(selectivity):对于某一个过滤条件,查询会从表中返回多大比例的数据基数(cardinality):在查询计划中常指算子需要处理的行数

2.2.2 统计信息收集方式

a. 在DDL里指定需要收集的统计信息,数据库会在数据写入时收集或更新统计信息

b. 手动执行explain analyze statement,触发数据库收集或者更新统计信息

c. 动态执行

2.2.3 统计信息的问题

      假设列和列之间是独立的,列的值是均匀分布——这个假设经常与现实不符