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

66 阅读2分钟

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

SQL 处理流程

SQL语句的处理顺序:Parser -> Analyzer -> Optimizer -> Executor

因为SQL是一种声明式的语言,所以这个处理流程其实就是把SQL语句解析成数据库应该执行的物理操作,因此在数据量大、查询操作复杂的场合下,查询优化的作用是非常重要的。

查询优化器

Rule-based Optimizer(RBO)

顾名思义,RBO是一种基于规则的优化器,RBO根据关系代数重写查询,关系代数貌似是在离散数学中学过的内容,离散数学我就没学明白,所以关系代数我也不太懂,不过没关系,无非就是一些关系之间的等价变换。

RBO的实现通常基于经验归纳,它的内部会维护一张表,表中越靠前的方式优先级越高,RBO会简单地匹配表中的执行方式,选择优先级最高的方式执行。

因此RBO根据经验快速选择抄近路,优化速度比较快,同样的,有些经验在今天庞大的数据量以及快速变化的环境中不一定适用,因此RBO不容易得出最优解。

Cost-based Optimizer(CBO)

CBO是在RBO之后出现的,它基于物理层面执行计划的代价,从预先生成的一组可能被执行的查询计划中选择代价最小的计划执行,因此CBO具有动态规划的特性,对数据更敏感。

CBO推导过程有两个关键的参数:选择率selectivity和基数cardinality。

cardinality是对目标SQL的某个具体执行步骤的执行结果所包含记录数的估算值,通常情况下,cardinality越准确,生成的执行计划就会越高效。

selectivity是施加指定谓词条件后返回结果集的记录数占未施加任何谓词条件的原始结果集的记录数的比率,selectivity越小,可选择性就越好。

社区开源优化器Calcite

需要先安装OpenJDK,然后构建calcite:

git clone https://github.com/apache/calcite.git
cd calcite
./gradlew build