本系列主要参考<PostgreSQL技术内幕:查询优化深度探索>
PostgreSQL的官方 源代码地址,git地址是git://git.postgresql.org/git/postgresql.git
Github上的 镜像
查询优化
查询优化器相对于数据库用户的优势
- 优化方案设计复杂,超出人脑
- 优化器有着用户不知道的统计信息
- 数据库数据变化,原优化方案不适用
优化的两个层次
关系模型
这里是一些讲数据库的书都会共同讲到的基础知识,包括关系代数和谓词演算。这里把里面的符号备忘以下
符号 | 含义 | 来源 |
---|---|---|
σ \sigma σ | 选择 | 关系代数 |
Π \Pi Π | 投影 | 关系代数 |
× \times × | 笛卡儿积 | 集合论 |
÷ \div ÷ | 除法 | |
∪ \cup ∪ | 并集 | 集合论 |
− − − | 差 | 集合论 |
∩ \cap ∩ | 交集 | |
⋈ \Join ⋈ | 连接 | |
⟕ ⟕ ⟕ | 左外连接 | |
⟖ ⟖ ⟖ | 右外连接 | |
⟗ ⟗ ⟗ | 全外连接 | |
⋉ ⋊ ⋉ ⋊ ⋉⋊ | 半连接 | |
⊳ \rhd ⊳ | 反半连接 | |
θ θ θ | θ连接 | |
ρ ρ ρ | 改名 | |
← ← ← | 赋值 | |
γ \gamma γ | 分组 |
对于关系代数的优化主要是将选择和映射进行下推
物理优化
B+树
B树是一个每级有[m/2,m]的节点的树
B+树在B树的基础上添加了下一节点指针和页内最大地址
hash表
排序
物理连接的MergeJoin也需要排序
物化
物化也可以看作是缓存,方便中间结果多次使用
物理路径
物理路径分为扫描路径和连接路径,前者针对单个关系,处理选择和投影,后者针对多个表,处理笛卡尔积,一般扫描路径是叶节点,是为连接路径做准备的
扫描路径
- 顺序扫描
- 索引扫描
会带来随机读的问题,一般配合位图使用 - 快速索引扫描
如果只根据索引就能得到想要的数据
连接路径
- Nestlooped Join
- 一般情况下复杂度是 O ( m ∗ n ) O(m*n) O(m∗n)
- 内表路径是索引扫描路径时复杂度是 O ( log n ) O(\log n) O(logn)
- 内表是一个索引扫描时复杂度 O ( m log n ) O(m\log n) O(mlogn)
- 内表比较小时可以先hash,这时复杂度是 O ( m ∗ n / N ) O(m*n/N) O(m∗n/N)
- 也可以两个表都排序做Merge Join
物理连接的选择
- 自下而上的动态规划
- 自上而下先逻辑查询树再枚举各种物理可能
- 随机搜索,例如遗传算法