引言
从今天开始,我将和大家一起学习查询执行(executor)模块中的内容。查询执行是数据库体系结构中不可或缺的一部分,对上执行查询优化(optimizer)产生的最优执行计划,对下与存储引擎(storage)息息相关。学习了解查询执行,对我们理解掌握数据库的执行过程有着重要意义。
首先,我们先来了解一下从查询解析到查询执行之间的过程,以及查询执行阶段执行的是什么。
查询树
想要了解查询执行的过程,那就离不开查询树。查询树用树形结构表示SQL语句的内部形式,反应了SQL语句的语法结构和逻辑关系。查询树这里介绍三种,分别是查询语法树、查询优化树、查询执行树。
查询语法树
查询语法树的叶子结点表示关系(表),内部结点表示关系代数操作(例如选择、投影、连接)。查询语法树在查询解析阶段可以直接通过词法分析和语法分析从SQL语句生成。例如对于SQL语句:
select C.c
from A,B,C
where A.x=B.y and B.y=C.z and A.a<10
可以生成如下图所示的查询语法树。
查询优化树(执行计划树)
查询优化树是一种对查询语法树进行优化后的形式,它利用一些等价变换规则和启发式规则,对查询语法树进行重组,剪枝等操作,以减少查询的执行代价。
常用的启发式规则有:
- 尽可能早执行选择运算,选择运算可以减少关系的元组数,减少后续操作的开销。
- 尽可能早执行投影运算,投影运算可以减少关系的属性数。
- 尽量将投影运算和选择运算同时进行,以避免重复扫描。
- 将选择运算和笛卡尔积运算合并为一个连接运算,因为连接运算可以利用索引或者哈希散列等技术加速数据的匹配。
- ······
查询优化树只是对查询语法树进行了一些优化,可能会改变执行的中间结果,但不会改变执行返回的最终结果。查询执行阶段将会按照此优化过后的查询树的逻辑进行操作,因此又可以称查询优化树为执行计划树。
例如经过优化,可以把上图中的询语法树转变为下图的查询优化树。
查询执行树
执行器根据查询优化阶段产生的查询优化树,对其进行物理实现,例如对每一个结点进行初始化,分配内存等操作,将其转为查询执行树。注意:查询执行过程和查询执行树的建立过程是同时的,并不存在先生成查询执行树,再查询执行。
火山模型
火山模型将查询执行树的每一个结点抽象成一个操作,这些操作也称为算子。每个算子都完成一项单一功能,例如投影、选择、扫描等,所有算子组合起来,实现了用户的查询目标。执行过程中,上层算子调用下层算子,并对下层算子的返回结果进行某一操作,然后将结果返回给更上层算子,这样形成了一个递归调用的过程。例如下图(网上摘取)所示。
opengauss也采用火山模型作为执行的逻辑架构,因为火山模型将每一个执行操作封装成一个算子来进行处理,每一个算子可以单独抽象实现,不需要关心其他算子的执行逻辑,拥有良好的模块化属性。
小结
这一节讲述了从查询语句到生成查询执行树所经历的过程,opengauss所采用的火山模型,得知查询执行模块是对查询优化模块所生成的执行计划树进行操作。接下来我会对执行阶段的过程做一些简要的讲解。