#database
# 1. Query Plan
SQL 语句 -> Query plan。
Operators 组织成 tree 的形式,数据从 leaves 流向 root,root 的输出就是查询结果。
-------------
# 2. Processing Models
## 2.1 Iterator Model
^4a72bd
最常见,绝大多数 row-based DBMS 会使用。
每个 operator 实现一个 `next` 函数:
- 每次调用 `next`,返回一个 tuple 或者 null marker(表示数据结束)
- operator 循环调用 children 的 `next` 来获取 tuples 进行处理
**pipeline breaker**:
operator 阻塞直到 children 吐出它们所有的 tuples。如 join、subquery、order-by
该模型下 LIMIT 很容易实现。
## 2.2 Materialization Model
每个 operator 一次性处理完所有的 input,并且一次性地输出所有的 output。
> The operator "materializes" its output as a single result.
适合 OLTAP workloads:
一般一次只访问少量的 tuples,优势在于**函数调用很少**。
不适合 OLAP 中间结果很大的查询:
因为可能需要将结果置换到磁盘。
## 2.3 Vectorization Model
类似 [[12-query-execution-1#2.1 Iterator Model | iteraotr model]] ,但 `next` 函数每次不是返回一个 tuple,而是返回**一批** tuples。
优势:
- 一次可以处理一批数据
- 有利于 SIMD
--------
# 3. Access Modes
## 3.1 Sequential Scan
优化:
- Prefetching
- Parallelization
- Buffer Pool Bypass
- Zone map、Late Materialization、Heap Clustering
### Zone map
- 可以单独的 zone map pages
- 缺点:
需要有维护开销
因此不适合 OLTP(更新多),更适合 OLAP(写一次读很多次)
### Late Materialization
- 通常更适用于 column store(每列数据是分散的),如果是 row store 一行的数据已经在一起。
- 每个 operator 传递尽可能少的信息(如 record id、column id)给下一个 operator
- 示例
```SQL
SELECT AVG(foo.c)
FROM foo JOIN bar
ON foo.b = bar.b
WHERE foo.a > 100
```
- SELECTION:只需要 a 列
- JOIN:只需要 b 列
- AVG:只需要 c 列
因此 operator 之间可以只传递 offsets,需要时根据 offset 去取数据
**重点:** 需要知道 query plan 的不同部分需要哪些数据
### Heap Clustering
或者叫 clustering index。
按照 clustering index 的顺序存储数据。
## 3.2 Index Scan
DBMS 挑选一个/多个索引来查找 query 需要的 tuples。
要点:quickly、限制无用功(避免读取不需要的 tuples)
使用哪个索引取决于:
- 索引包含了什么 attributes
- 查询引用了什么 attributes
- attribute 的值域
- predicate composistion
- 索引是否唯一
由 query optimizer 负责选择索引。
### Multi-Index Scan
每个索引都有帮助,selective 程度很高 **->** 使用 Multi-Index Scan
1. 使用每个索引计算 record ids 集合
2. 基于查询的谓词,合并这些集合(union vs intersect)
3. 获取 records,然后应用剩余的谓词
Postgres 称之为 [Bitmap Scan](https://www.postgresql.org/message-id/
[email protected]) 。
### Index Scan Page Sorting
问题:直接按照索引去获取 tuples 会导致大量随机访问(index 的顺序跟 tuple 存储的顺序不一样)
**page sorting:**
1. 先找出所有需要的 tuples 的 record ids
2. 基于它们的 page id 进行排序
**order-by 消除:**
如果索引的顺序跟 order-by 指定的顺序一样
--------------------
# 4. Expression Evaluation
expression tree 存在于 operator 内部,比如 filter operator 中的 where 从句。
不同的 tree node 代表了不同的表达式类型:
- Comparisons (=,`<` ,`>`, `!=`)
- Conjunction(`AND`),Disjunction(`OR`)
- Arithmetric operators(`+`, `-`, `*`, `/`, `%` )
- Constant Values
- Tuple Attribute References
- Function Calls
expression evaluation 需要遍历 expression tree,会比较慢,优化:
- JIT compilation
> Expression trees are **flexible** but **slow**