Skip to content

Commit 906ad8e

Browse files
authored
feat(doc): change README.md (#25)
1 parent f860cad commit 906ad8e

6 files changed

Lines changed: 331 additions & 107 deletions

File tree

README.md

Lines changed: 115 additions & 107 deletions
Large diffs are not rendered by default.

README_ZH.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# KipSQL
2+
3+
4+
> build the SQL layer of KipDB database.
5+
>
6+
7+
# SQL layer 需要作什么
8+
9+
- SQL API:用户接口,接收来自外界的请求。
10+
- 解析器(Parser):将SQL文本转换为抽象语法树(AST)。
11+
- 语义分析:AST树合法性校验
12+
- 优化器(Optimizer)
13+
- 逻辑优化:将AST树转换为优化的逻辑查询计划。
14+
- 物理优化:将逻辑查询计划转换为[物理查询计划](https://www.zhihu.com/search?q=%E7%89%A9%E7%90%86%E6%9F%A5%E8%AF%A2%E8%AE%A1%E5%88%92&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22article%22%2C%22sourceId%22%3A%22557876303%22%7D),供集群中的一个或多个节点执行。
15+
- 执行器Executor:通过向底层kv存储发出读写请求(发送到事务层),来执行物理计划。
16+
17+
流程图可以参考TIDB的,非常明了。
18+
19+
![Untitled](assets/Untitled.png)
20+
21+
# SQL引擎设计
22+
23+
### 期望支持的SQL语法类型
24+
25+
- 数据定义语言DDL(Data Definition Language):对数据库中资源进行定义、修改和删除,如新建表和删除表等。
26+
- 数据操作语言DML(Data Manipulation Language):用以改变数据库中存储的数据内容,即增加、修改和删除数据。
27+
- 数据查询语言DQL(Data Query Language):也称为数据检索语言,用以从表中获得数据,并描述怎样将数据返回给程序输出。
28+
29+
### Parser
30+
31+
实现解析器的逻辑比较复杂,项目初始阶段可以先使用现成的库
32+
33+
parser选型
34+
35+
[https://github.com/sqlparser-rs/sqlparser-rs](https://github.com/sqlparser-rs/sqlparser-rs)
36+
37+
```rust
38+
use sqlparser::dialect::GenericDialect;
39+
use sqlparser::parser::Parser;
40+
41+
let sql = "SELECT a, b, 123, myfunc(b) \
42+
FROM table_1 \
43+
WHERE a > b AND b < 100 \
44+
ORDER BY a DESC, b";
45+
46+
let dialect = GenericDialect {}; // or AnsiDialect, or your own dialect ...
47+
48+
let ast = Parser::parse_sql(&dialect, sql).unwrap();
49+
50+
println!("AST: {:?}", ast);
51+
```
52+
53+
但sqlparser-rs库只能提供词法分析和语法分析,生成查询树,不能进行语义分析,也就是合法性校验。因此我们将 sqlparser库进行封装,增加语义分析功能
54+
55+
## 语义分析
56+
57+
- 及时校验报错
58+
- 标识符resolve
59+
- 数据库、表、字段、属性存在性、正确性校验
60+
- 语义逻辑限制
61+
- group by和select的item的关系
62+
- distinct和order、group by的关系
63+
- select item是否在source relation中
64+
- 。。。
65+
- SQL片段表达式的正确性
66+
- 分别分析各个最小表达式返回类型、表达式正确性,例如where expr1 = subquery 就要求验证 “=” 两边的结果类型可比较
67+
- 这些表达式组合后的正确性,例如 expr1 and expr2 就要求 expr1/2 表达式的返回结果必须是boolean型才能 进行 AND操作
68+
- 。。。
69+
- 分析结果,作为可选参数传给 生成 逻辑计划/物理计划 的planner,作为参数进一步被转换应用
70+
- 例如可以用functionExpression来转换生成具体的 函数调用,这个过程需要知道 func(A,B) C的参数类型、返回类型等,才能对应调用具体的函数
71+
72+
## Optimizer
73+
74+
### 优化器概述
75+
76+
![Untitled 1](assets/Untitled%201.png)
77+
78+
### **查询优化器的核心目的是**
79+
80+
- 根据query生成的plan,在可接受时间内,快速找到一个语义等价的、查询最高效的 查询执行计划
81+
82+
### **其目标最核心的三个要点,尽可能同时满足**
83+
84+
- 时间可接受的,快速的
85+
- 语义等价
86+
- 查询最高效的
87+
88+
未来实现这个目标,学术界和工业界在不断努力,其中我们常说的查询优化器类型有CBO、RBO、HBO这些。
89+
90+
HBO(Heuristic-Based Optimizer)和RBO(Rule-Based Optimizer)都是数据库查询优化器的早期实现,它们都有一些局限性,这些局限性导致它们无法满足当今复杂的数据库系统的需求。这就是为什么需要引入CBO(Cost-Based Optimizer)。
91+
HBO使用启发式算法来选择最优的查询执行计划。它将查询优化过程视为一个搜索问题,尝试使用一些经验法则来指导搜索。然而,这些启发式规则可能不适用于所有情况,导致HBO无法找到最优的查询执行计划。
92+
93+
RBO是另一种优化器,它使用一系列的规则来指导查询优化过程。这些规则通常是基于查询语法和数据模式的,并且不考虑查询的复杂度和数据分布等因素。因此,RBO通常只适用于简单的查询,对于复杂的查询无法找到最优的执行计划。
94+
95+
CBO引入了代价模型的概念,它基于查询代价来选择最优的查询执行计划。代价模型是基于统计信息和数据库结构的,并且考虑了查询的复杂度和数据分布等因素。CBO使用代价模型来评估每个可能的查询执行计划的代价,并选择代价最小的执行计划作为最终的执行计划。因此,CBO能够处理更加复杂的查询,并且能够找到最优的查询执行计划。
96+
而CBO核心是基于代价的来展开的, 如果代价无法估算正确,那么整个优化结果就是错误的。而估算代价的过程也是个复杂的过程,想要有限时间内,快速从所有的plan tree选择最优解 已经被证明过是个NP-Hard问题。
97+
这就导致CBO始终没有一个最完美、最全面、最准确的解决方案。
98+
**对于一个CBO而言,其核心组件有3个,业界把这3个地方抽象为如下图,这也是近年来工业界、学术界的努力聚焦在的细分领域**
99+
100+
- **Cardinality Estimation 基数估算**
101+
- **Cost Model 代价模型**
102+
- **Plan Enumeration 计划枚举搜索**
103+
104+
105+
106+
![Untitled 2](assets/Untitled%202.png)
107+
108+
**如上图,查询优化器第一步就是有做好基数估算和代价模型。**
109+
110+
- 基数是指一个operator操作数据的规模,例如TableScan这种operator,他的基数就是表的数据量,如果是hashjoin这种operator,那么就是具体数据的NDV个数。如果基数错误,这就导致代价估算的基数就错了,评估得到的代价肯定也是错误的。例如分不清大小表,把大表broadcast到各个节点,小表进行分区join。
111+
- 代价模型是指各种operator在各种数据的计算代价公式,例如tableScan 1行需要多少时间,filter 1一行需要多少时间,是否需要一些影响因素系数等等,不同的代价公式,会得出不同的代价结果,导致选出来的plan千差万别。
112+
113+
**其次就是plan enumeration,其作用就是在众多plan中,快速选取cost代价最小的plan**
114+
115+
- 由于枚举plan这个过程是随着join表个数,搜索空间大小会指数变大,全部罗列出plan在挑选最优plan是不现实的
116+
- 业界通常是使用bottom-up的动态规划办法【System R】、top-down的memorization办法【volcano&cascade系列】、随机join顺序的办法进行【PG 11之前】
117+
- 从历史发展来看
118+
- 随机join肯定是个概率问题,后期演进空间不大;
119+
- 而bottom-up的架构,就涉及扩展性和各种迭代开发问题,导致发展缓慢;
120+
- 目前比较公认的是 top-down的方式,而top-down典型的又volcano 系列和cascade系列的查询优化器
121+
- 其中volcano的优化器有 早期的Apache calcite
122+
- cascade系列的早期 MS SqlServer,Columbia,后来columbia合入到PostgreSQL里面。比较新的开源实现是ORCA这个,相对简单。阿里云ADB也是这种cascade架构。
123+
124+
**而针对这三个核心的组件,结合一些公布的学术动态,未来可能得发展方向如下:**
125+
126+
- Cardinality Estimation
127+
- Learning-based methods 最近两年很多这方面的研究工作
128+
- Hybrid methods 混合多种方法,互相影响相辅相成
129+
- Experimental study 更多实验验证这些 方法的有效性和准确性,否则很多研究还停留在学术上
130+
- Cost Model
131+
- cloud database systems 结合一些云环境上的代价估算,例如多云的运算时间、云环境付费成本
132+
- learning-based methods 基于一些机器学习的方式估算代价,例如对大量的operator进行训练得到各种输入下,operator的代价情况,以此来估算一个新的query的plan的所有operator 代价的sum总代价
133+
- Plan Enumeration
134+
- Handle Large queries 对于大查询的一些处理,需要深入研究
135+
- Learning-based methods 持续研究机器学习的方式,目前主流的还是非机器学习的方案。
136+
137+
![Untitled 3](assets/Untitled%203.png)
138+
139+
经过优化器生成物理计划投喂到执行器
140+
141+
## Executor
142+
143+
执行引擎采用 Volcano 模型
144+
145+
通过优化器得到的物理查询计划树会转换为一个执行器树,树中的每个节点都会实现这个接口,执行器之间通过 Next 接口传递数据。比如 select c1 from t where c2 > 1; 最终生成的执行器是 Projection->Filter->TableScan 这三个执行器,最上层的 Projection 会不断的调用下层执器的 Next 接口,最终调到底层的 TableScan,从表中获取数据。
146+
147+
![Untitled 4](assets/Untitled%204.png)
148+
149+
> 后期可以考虑使用Velox
150+
>
151+
>
152+
> Velox 接受一棵**优化过的** `PlanNode` Tree,然后将其切成一个个的线性的 `Pipeline``Task` 负责这个转变过程,每个 Task 针对一个 PlanTree Segment。大多数算子是一对一翻译的,但是有一些特殊的算子,通常出现在多个 Pipeline 的**切口**处,通常来说,这些切口对应计划树的**分叉处**,如 `HashJoinNode``CrossJoinNode`, `MergeJoinNode` ,通常会翻译成 XXProbe 和 XXBuild。但也有一些例外,比如 `LocalPartitionNode` 和 `LocalMergeNode` 。
153+
>
154+
> ### velox 的必要性
155+
>
156+
> 不同数据处理系统之间的主要差异在于
157+
>
158+
> - 语言前端层面:SQL、dataframe、其他DSL等
159+
> - 优化器
160+
> - 任务划分:分布式场景下如何划分数据/任务
161+
> - IO 层
162+
>
163+
> 而它们的执行层都是十分相似的
164+
>
165+
> - 类型系统
166+
> - 数据在内存中表示/layout
167+
> - 表达式求值系统
168+
> - 存储层、[网络序列化](https://www.zhihu.com/search?q=%E7%BD%91%E7%BB%9C%E5%BA%8F%E5%88%97%E5%8C%96&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra=%7B%22sourceType%22%3A%22article%22%2C%22sourceId%22%3A%22620275762%22%7D)
169+
> - 编码
170+
> - 资源管理原语
171+
>
172+
> velox就是致力于成为一个通用的执行层:接受经过optimizer优化过后的查询计划,使用本地资源执行查询计划。但是不做SQL parser、optimizer的工作。
173+
>
174+
175+
## 后续调研工作
176+
177+
table 到 kv 映射关系的处理
178+
[参考TinySQL中TableCodec设计](https://github.com/talent-plan/tinysql/blob/course/courses/proj1-part2-README-zh_CN.md)
179+
180+
优化器的具体实现
181+
[DataFusion Query Optimizer](https://github.com/apache/arrow-datafusion/blob/aae7ec3bdb64bf0346249ccb9e44abdc29880904/datafusion/optimizer/README.md#L4)
182+
183+
[tinysql优化器文档](https://github.com/talent-plan/tinysql/blob/course/courses/proj4-README-zh_CN.md)
184+
185+
第一阶段可以实现一个简单优化器
186+
187+
velox 能否接入KipDB作为存储引擎
188+
189+
# Reference
190+
191+
192+
[TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现](https://cn.pingcap.com/blog/tidb-source-code-reading-5)
193+
194+
[Facebook Velox 运行机制全面剖析](https://zhuanlan.zhihu.com/p/614918289)
195+
196+
[Velox: Meta’s Unified Execution Engine](https://zhuanlan.zhihu.com/p/620275762)
197+
198+
[TinySQL 实现总结](https://waruto.top/posts/tinysql-impl/)
199+
200+
[揭秘 TiDB 新优化器:Cascades Planner 原理解析](https://zhuanlan.zhihu.com/p/94079481)
201+
202+
[TiDB 源码初探](https://zhuanlan.zhihu.com/p/24564238)
203+
204+
[Push-Based Execution in DuckDB - Mark Raasveldt](https://www.youtube.com/watch?v=MA0OsvYFGrc)
205+
206+
[Push-Based Execution in DuckDB](https://dsdsd.da.cwi.nl/slides/dsdsd-duckdb-push-based-execution.pdf)
207+
208+
[Paper Reading: MonetDB/X100: Hyper-Pipelining Query Execution](https://frankma.me/posts/papers/monetdb-hyper-pipelining-query-execution/)
209+
210+
[查询执行 | Databend 内幕大揭秘](https://psiace.github.io/databend-internals/docs/the-basics/executor-in-query-process/)
211+
212+
[[][不会游泳的鱼]SQL引擎发表、落地论文总结](https://distsys.cn/d/179-zhuan-bu-hui-you-yong-de-yu-sqlyin-qing-fa-biao-luo-di-lun-wen-zong-jie)
213+
214+
[Apache Arrow:一种适合异构大数据系统的内存列存数据格式标准](https://tech.ipalfish.com/blog/2020/12/08/apache_arrow_summary/)
215+
216+
[TPC-H benchmark of Hyper and DuckDB on Windows and Linux OS - Architecture et Performance](https://www.architecture-performance.fr/ap_blog/tpc-h-benchmark-of-hyper-and-duckdb-on-windows-and-linux-os/)

assets/Untitled 1.png

57.8 KB
Loading

assets/Untitled 3.png

50.3 KB
Loading

assets/Untitled 4.png

98.1 KB
Loading

assets/Untitled 5.png

355 KB
Loading

0 commit comments

Comments
 (0)