关系数据库 Query_Execution
关系数据库 Query Execution 的流程
在关系型数据库中, 一条 Query 语句执行的流程如下:
DBMS将Quey语句翻译成特定的内部抽象语言, 通常有两种 Query Plan
- logical Plan: 使用关系代数描述 Query Plan, 描述关系操作符或者非关系操作符
- physical: 描述这些操作符的实际动作
Query 处理的三个阶段
- 解析以及重写 Query, SQL->logical plan
- Query 语言优化
logical plan -> 优化的 logical plan -> physical plan - Query Execution: 在数据库中执行这个 physical plan, 就是 Processing Model 作用的位置.
Processing Model
Processing Model 在解析节点不起直接作用, 起作用的主要阶段是优化节点(Optimization), 优化器会根据数据库的统计信息(如表大小, 索引情况)和 SQL 查询条件, 生成一个最优的执行计划, 这里可能包括选择最合适的索引, 决定连接方式等, 以尽量减少资源消耗和提升查询速度.
Processing Model 在这个阶段开始生效, 帮助定义 SQL 优化器在构建执行计划时如何考虑数据的存储和读取方式.
根据调用数据库操作符顺序的不同, 我们通常将 Processing Model 分为两类, 分别是自上而下, 与自下而上的方式, 类似于语言编译的流程.
常见的三种Execution模型是:
- Iterator Model
- Materialization Model
- Vectorized / Batch Model
Iterator Model
Iterator Model 也叫 Volcano or Pipeline model, 是最常用的 Query Execution 模型, 几乎在所有的基于行的数据库中都使用的是这种模型.
迭代模型(Iterator Model) 的工作方式是为每一个数据库的操作符添加一个 Next
函数. 在我们的 Physical Query Plan 中, 迭代模型会递归的调用孩子节点的 Next()
函数, 直到根节点, 当到达叶子节点后, 开始获取数据库中的一行数据(tuple), 然后返回到父节点处理. 在读取下一个tuple之前, 每一个tuple会被尽可能地向上处理. 在基于磁盘地数据库中, 这种方式十分有效, 因为这种方法允许我们充分地使用内存中的tuples.
我们用下图描述 Iterator Model 处理地 Query 地基本流程.
上图中, 从右到左分别是一个数据库Query的SQL语句, Logical Query Plan 语句, 以及使用迭代模型(Iterator Model) 的Physical Query Plan. 上述的箭头可以看出迭代模型会将每次读取的tuple返回到父节点的Next()函数中.
当Iterator Model中的Next函数满足下面两个条件时, 迭代模型(Iterator Model)中的操作符可以被相互独立的实现, 不受父节点与子节点的影响, 能够实现Pipeline的效果. 这两个条件是:
- 在每个操作符调用Next函数的时候, Next函数仅返回一个tuple, 或者返回空(当没有tuple被返回的时候).
- 操作符会实现一个循环, 在每一个孩子节点上调用Next()函数, 并处理Next函数返回的tuples.
满足了上述操作符相互独立的条件后, 迭代模型在在DBMS中可以流水线式的处理Query Plan, 它可以尽可能的使用操作符处理 tuple, 在下一个操作符读取之前. 这种处理方式就是迭代模型(Iterator Model)中的Pipeline.
简单点说就是, 每次处理一行, 尽可能地将这一行的所有操作处理完, 例如在上面的图中, 在节点5中需要读取S数据库中的tuples, 假如在节点5读取到了tuple_A, 当节点4正在处理tuple_A的时候, 节点5就可以开始继续读取后面的tuples. 这也就是所谓的流水线式的并行策略, 也就是Pipeline. 但是一些操作符由于操作的特性, 需要孩子节点获取所有tuples后才可以继续执行, 例如上图中的节点2中的Join()连接操作, 常见的还有Order By, 这些操作符被称为 pipeline breakers.
输出控制, LIMIT() 操作限制可以很容易的作用到迭代模型中, 当到达LIMIT限制后不再invoke tuples即可.
Materialization Model
Materialization Model 本质上是一种特殊的迭代模型(Iterator Model), 不同点是 Materialization Model 会一次性的处理所有的输入与输出. 换句话说, Iterator Model 在每个操作的Next()函数中, 每次处理一个从孩子节点返回的tuple, 但是在Materialization Model中, 孩子节点会一次性的将孩子处理后的所有tuples返回给父节点处理. 实际过程中, DBMS在执行的过程中, 向下调用函数的时候会通知后续的操作符需要多少tuples, 因此整个Materialization Model的输出是一整个 tuple (NSM) 或者 a subset of columns (DSM).
Materialization Model 的实现流程如下:
可以看到每个操作符都维持一个Out数组, 用于返回处理的所有的tuples, 同时还有一个Output函数, 处理所有的tuples. 一个孩子节点将Output的结果返回给父节点.
每一个操作符会带有一个Output函数, 这个Output函数满足下面的特点:
- 操作符一次性处理所有孩子节点的tuples.
- 该操作符的Output函数返回该操作可以返回的所有的tuples, 当操作结束执行后, 不会再生成任何新的tuple.
这种方式更适合OLTP形式的数据库, 因为