0
点赞
收藏
分享

微信扫一扫

<postgreSQL查询优化深度探索>之第二章:查询树学习总结


文章目录

  • ​​一、Node的结构体​​
  • ​​二、Var结构体​​
  • ​​三、RangeTblEntry结构体​​
  • ​​四、RangeTblRef结构体​​
  • ​​五、JoinExpr结构体​​
  • ​​六、FromExpr结构体​​
  • ​​七、Query结构体​​
  • ​​八、查询树的展示​​
  • ​​九、查询树的遍历​​
  • ​​十、执行计划的展示​​
  • ​​十一、小结​​

一、Node的结构体

typedef struct List
{
NodeTag type; /* T_List, T_IntList, or T_OidList */
}List;

typedef struct Query
{
NodeTag type;
}Query;

都能通过Node结构体的指针Node*来表示List*。Query*;
通过查看Node类型的中的NodeTag就能区分该Node指针所代表结构体的实际类型

二、Var结构体

Var结构体表示查询中涉及的表的列属性,在SQL语句中,投影的列属性、约束语句中的列属性都是通过Var来表示的

typedef struct Var
{

}Var;

三、RangeTblEntry结构体

RangeTblEntry(范围表,RTE)描述了查询中出现的表,他通常出现在查询语句的FROM子句中,范围表中既有常规意义上的堆表、还有子查询、连接表等。

typedef struct RangeTblEntry{}RangeTblEntry;;

四、RangeTblRef结构体

每个RangeTblEntry范围表在Query->rtable链表中只保存一份,其他地方使用到范围表都使用RangeTblRef代替

  • RangeTblRef是RangeTblEntry的引用
  • 由于RangeTblEntry在Query->rtable中的位置是确定的,所以可以用rtindex来标识RangeTblEntry在Query->rtable中的位置

typedef struct RangeTblRef
{
NodeTag type;
int rtindex;
} RangeTblRef;

  • eg:

select * from student left join score on true, (select * from teacher) as t,course, (values(1,1)) as num(x,y), generate_series(1,10) as gs(z);

各种类型的RangeTblRef如下:

<postgreSQL查询优化深度探索>之第二章:查询树学习总结_database


<postgreSQL查询优化深度探索>之第二章:查询树学习总结_执行计划_02

五、JoinExpr结构体

typedef struct JoinExpr
{
}JoinExpr;

在查询语句中若显示地指定两个表之间的连接关系,eg:a left join b on pab,则需要JoinExpr结构体

  • eg:rtable和jointree是Query的成员,其他以此类推

三表个表需要2个JoinExpr
select * from student left join score on true left join scorse on score.cno=course.cno;

六、FromExpr结构体

FromExpr和JoinExpr表示表之间的连接关系的结构体

  • FromExpr中各个表之间的连接关系是inner join
  • FromExpr->fromlist中可以保存任意多个表

typedef struct FromExpr{
};

  • eg:varno表示第几列

select * from student,score left join course on score.cno=course.cno

七、Query结构体

Query结构体是查询优化模块的输入参数

  • 来自语法分析模块
  • 一个sql语句在执行过程中,经过词法分析、语法分析和语义分析后会产生一颗查询树
  • 查询优化模块在获取到查询树之后,开始对查询树进行逻辑优化,即对查询树进行等价变换,将其重写成一颗新的查询树,这个的查询树作为物理优化的输入参数,进行物理优化

typedef struct Query{
}Query;

  • eg:

select st.sname, c.cname,sc.degree from student st, course c inner join score sc on c.cno=sc.cno where st.sno=sc.sno;

八、查询树的展示

提供的参数查看查询树和执行计划树

<postgreSQL查询优化深度探索>之第二章:查询树学习总结_执行计划_03

在逻辑优化阶段需要对查询树进行重写,可以增加elog_node_display函数来打印查询树重写前和重写后的区别;

九、查询树的遍历

PG中所有的node都是以类似于类的方式实现的,so:我们可以由基类node的指针代表任何节点,并通过Nodetag快速识别当前NOde的真实类型。

  • PG通过query_tree_mutator函数和query_tree_walker函数(递归思想)遍历查询树
  • query_tree_mutator函数和query_tree_walker函数借助expression_tree_mutator函数(作用:遍历查询树,且可能会修改某个结构体的值)和expression_tree_walker函数(增加或者删除查询树中的某个节点)来实现

十、执行计划的展示

查询优化的主要目的就是将一个查询树(关系代数)转换为一个代价最低的非完全二叉树的执行式

  • EXPLAIN打印的就是这个非完全二叉树,算式中的每一个节点对应一个物理路径
  • eg:

十一、小结

<postgreSQL查询优化深度探索>之第二章:查询树学习总结_执行计划_04




举报

相关推荐

0 条评论