Query Execution
Processing Model
定义了一个系统如何执行一个查询计划。
Iterator Model
每个query plan operator都采用了一个叫做Next的函数。每一次调用的时候,每个运算符要么返回一个tuple,要么返回一个null。就类似于一个DFS,一次调用一直从叶子节点取一个tuple返回到调用者。这么做的一个目的是为了使读入到内存中的tuple存在尽可能长的时间。也叫做pipeline model。
有一些operators会阻断掉pipeline,比如joins、subquery、order by。这些运算符不能一次只返回一个tuple,因此叫做pipeline breakers。
对于LIMIT命令非常友好。
Materialization Model
这种方法就是每一次调用是先把这个operator的结果全部收集起来,然后向上传递而不是一条一条地收集。适用于OLTP事务类型。如果是OLAP类型,则可能因为中间operator产生的数据太大被写入到磁盘中。
当然也有一种方法叫做Late Materialization。这种就是一次不把所有的数据向上传完,而是传一些关键的信息量,到最后需要用的时候,利用这些信息返回去取。而Materialization Model就不需要回取。
Vectorization Model
就是对Iterator Model的一种优化,一次Next不再是传一个tuple上去,而是传一块tuple上去。因为next函数调用的少了,所以对OLAP事务更友好。
Access Methods
查询树的最底层涉及到Access data,有不同的方法去获取数据。
Sequential Scan
基本的方法就是对于table中存的每一个page,从BufferPool中取出,然后遍历一遍。每调用一次next就会向后取一次,因此DBMS会保存一个内部的cursor来记录当前取到了哪一个page的哪一个slot。
Prefetching
先取一片pages放到内存池中而不是一次只取一个
Parallelization
用多个线程去扫描/处理
Zone Map
存关于一个page中信息的聚合函数值,在访问page前先看看zone map中的信息,能提前判断是否需要进入这个page中扫描。Zone Map一般放在一个单独的page中。类似bloom filter。
Late Materialization
只往上传例如offset等关键的信息,到最后需要的时候才进行计算,获取完整的信息,只适用于列存储的table。
Heap Clustering
Clustering的方式存储,有序可以使扫描更快。
Index Scan
如果有多个索引,数据库会利用这多个索引来得到多个数据的set,存到bitset中,做一次AND操作就能得到所有符合条件的tuples。
如果索引是unclustered的,就要先把要取的page id拿出来排序,然后一个个扫描。clustered index比较难以维护,如果中间的一个page满了要进行分裂就要做很多额外的处理。
Expression Evaluation
在Where语句中会出现的expression。可以构建成一棵语法树遍历一遍来求。
Parallel VS Distributed
Parallel数据库的资源在物理上相距非常近,communicate的速度非常快,并且代价非常低。
分布式数据库则正好相反。
Process Model
1.用每个worker来运行一个process,依赖于系统的调度器、共享内存(因为是不同的进程)。
2.用worker pool来分配进程,通常会预留一个进程用来处理系统管理员发送进来的指令。
3.一个进程多个线程。如果是多进程模式的话,一个线程崩溃了并不会使得整个系统崩溃,但是如果是多线程模式,一个线程崩溃了整个进程就会崩溃。线程切换效率更高,也不需要用到共享内存(使用的内存都在同一个进程中了),甚至还可以把线程绑定在CPU一个特定的核上运行。
Intra-Query Parallelism
并行地执行每个operator,每个operator都有对应的并行算法。将operators拆分成独立的实例,每个实例在不同的数据集上执行相同的函数。最后DBMS会插入一个exchange operator在query plan上去把child operator的结果给合并起来。
有三种exchange operators:
Gather:合并多个worker的结果成一个输出流。
Repartition:将多个输入流重新组合成多个输出流。
Distribute:将一个输入流分成多个输出流。
Inter-Query Parallelism
多个命令并行执行,同时还有一种叫做Inter-Operator Parallelism,这种就类似于pipeline parallelism,即我们用多个线程分别处理不同的operator,每当上一个operator处理完一个tuple时,我们可以直接把这个tuple扔给下一个operator来执行。
I/O Parallelism
有时候如果只把数据库存在一个磁盘上,这个磁盘的IO可能是瓶颈。我们可以把数据库存在不同的磁盘上。
Multi-Disk Parallelism
一个磁盘上存数据库的一部分信息,需要借助RAID,依赖于操作系统和设备,换一台设备方法可能就失效了。
Logical Partitioning
逻辑分区,即把一个logical table分成不相交的几个物理片段储存,这个分区对应用是不可见的!作为数据库的使用者不需要管下层的分区。
Vertical Partitioning
把table的不同属性分在不同的位置,需要存tuple information在最后重构origin record。
Horizontal Partitioning
直接把tuples划分成不同的部分存在不同的位置。