这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记
深入理解RDBMS
一条SQL的一生
Parser
解析器一般分为词法分析、语法分析、语义分析的等步骤
Optimizer
- 基于规则的优化
- 条件简化 对条件表达式进行简化
- 表连接优化
总是小表先连接 - Scan优化
选择合适的索引
- 唯一索引
- 普通索引
- 全表扫描
- 基于代价的优化
一个查询有多种执行方案,CBO会选择其中代价最低的方案真正的执行\- 什么是代价?
时间
具体表现为IO、CPU、NET、MEM
代价往往以整体为标准
- 什么是代价?
Executor
-
火山模型
每个operator调用next操作,访问下层operator,获得下层operator返回的一行数据,经过计算,将这行数据返回给上层- 优点
- 每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
- 缺点
- 每计算一条数据有多次函数调用开销,导致CPU效率不高
- 优点
-
向量化模型
每个operator每次操作计算的不再是一行数据,而是一批数据,计算完成后向上层算子返回一个Batch- 优点: 函数调用降低为1 CPU cache命中率更高 可以利用CPU提供的SIMD机制
-
编译执行 Executor
将所有的操作封装到一个函数里面,函数调用大幅度降低
llvm
可以将自己语言的源代码编译成LLVM中间代码(LLVM IR),然后由LLVM自己的后端对这个中间代码进行优化,并且编译到相应的平台的二进制程序。
存储引擎
- buffer Poll
- Change Buffer
- Adaptive Hash Index
- Log Buffer
事务引擎
- 原子性和Undo Log
undo log是逻辑日志,记录的是数据的增量变化,利用undo log可以完成事务的回滚,从而保证事务的原子性,同时也实现了多版本并发控制,解决了读写冲突和一致性读的问题。 - 一致性
一般由业务完成一致性校验 - Isolation与锁
- 读读-->Share Lock
- 写写-->Exclusive Lock
- 读写-->MVCC MVCC
- 读写互不阻塞
- 降低死锁频率
- 实现一致性读
- Durability与Redo Log
如何保证事务结束后,对数据的修改永久保存- 方案一:事务提交前页面写入磁盘
问题:随机IO和写放大 - 方案二: WAL(Write-ahead logging)
redo log是物理日志,记录是页面变化,他的作用是保证事务持久化
- 方案一:事务提交前页面写入磁盘