- 逻辑分解和物理优化产紧密
- 重写中,Query->Jointree通过Rangetblentry组织
- 逻分中,Rangetblentry将建立对应Reloptlnfo
- Rangetblentry对应范围表
- 对表描述,属逻辑层面
- 内部没提供和物理代价及物理路径相关的成员变量
- Reloptlnfo: 生成物理连接路径及计算路径代价,属物理层面
- 对表描述,属逻辑层面
- 査询树中约東条件是表达式,只保存表达式本身所需内容
- 逻辑分解将这些裸用Restrictlnfo封装
- 这样就可扩展表达式内容
- Restrictlnfo中记录约束条件在物理优化中需要的变量
- Query中,约束条件存放位置就是它原始语法位置
- 逻辑分解中,对它尝试下推
- Restrictlnfo是为在下推时能更好和Reloptlnfo结合
- 逻辑分解阶段基于等价类推理,生成隐含约束条件,
- A=B和约束条件B=C能够推导出新的约束条件A=C
- 基于这种推理在物理优化时能生成更丰富的连接路径
- 关系数据库引外和半连接,很多关系代数中的经典理论不适用
- 约束条件下推过程中
- 由于外连接引入导致一些连接条件被延迟下推(delay)
- 谓词下推、连接顺序交换、基于等价类的推理是査询优化难点
- 没透彻理解逻辑分解优化,物理优化理解就更难
4.1 创建RelOptInfo
- 查询树,基表信息以Rangetblentry放在Query->rtable中
- 查询优化后期,尤其物理优化, Rangetblentry保存的信息无法满足代价计算
- 因为每个基表都生成扫描路径
- 多基表间还产连接路径,且要计算这些路径代价
- 因此要新的RelOptInfo
4.1.1 RelOptInfo结构体
- 查询优化中,先面对FROM中表,称范围表
- 常規意义表
- 子查询
- 查询结果的组织为表状的函数(如Tablefunction)
- 处执行计划树的叶节点
- 是查询结果的基础,称基表
- 基用Reloptlnfo表示
- reloptkind是RELOPT_BASEREL
- 基表间可连接,连接产生的“中间”结果也可用Reloptlnfo表示
- reloptkind是RELOPT_JOINREL
- RELOPT_OTHER_MEMBER_REL类型的Reloptlnfo来表示
- 继承表的子表或UNION操作的子查询
- Reloptlnfo多功能,庞大,分多部分介绍
- 第一部分Reloptlnfo公共变量
- RELOPT_ BASEREL还RELOPT_JOINREL类型或其他类型
- 都用到这些变量
- consider_startup和consider_param_startup作用
- Pg记录启动代价和整体代价,
- 每条物理路径都会记录启动和整体
- 代价计算是在路径创建后进行
- 但Pg为提性,在连接路径创建前,会算一个初级的代价对连接路径“预检”,如果这条物理路径没优势,就不建
- 这样能节省创建路径的消耗
- consider_startup和consider_param_startup标识在“预检”时是否比较启动代价。
- 启动代价在有LIMIT时才重要(6章中关于代价介绍)
- tuple_ fraction>0时consider startup才有用
- param和startup类似
- 但针对参数化路径“预检”,且是在Semijoin和Antijoin中才起作用(参照set_base_rel_consider_startup
- 参数化路径目前只能是Nestloopjoin的内表路径,
- 它的启动代价的意义不大,
- 但Semijoin和 Enjoin
- 每次对内表只要匹到一条记录就可,这时启动代价就有意义
- 第二部分是基表(BASEREL)必用的
来源:CSDN
作者:fgh431
链接:https://blog.csdn.net/zhoutianzi12/article/details/104040888