PG里面一条SQL的处理流程

点击查看代码
客户端发起SQL语句,postmaster进程fork一个backend进程来对接(SQL语句会依次经过backed进程里面的解析器,分析器,重写器,计划器,执行器),最终返回处理的结果

一、一条sql语句(也就是一个字符串)会通过parsenode.h文件中的SelectStmt数据结构生成一颗语法解析树(这个阶段只会检查语法,不会检查语义)

二、分析器接收语法解析树,通过parsenode.h文件中的Query数据结构生成一颗查询树(这个阶段会检查语义,例如表是否存在,字段是否存在)

三、重写器会根据规则系统(pg_rule里面的规则)对查询树进行改写,生成一个新的查询树

四、计划器获取上面的查询树进行以下三个步骤:
1、先创建PlannerInfo数据结构存储查询树,可查询关系信息和路径等
2、预处理,对PlannerInfo里面的查询树进行一些预处理(例如2+2直接改为4,not(not a)直接改为a等操作)
3、对所有可能的路径进行代价估算并找到代价最小的路径(创建一个RelOptInfo数据结构来存储访问路径及代价,估计所有路径的代价(通过costsize.c文件里面的各种函数来估算代价),并将访问路径添加到RelOptInfo数据结构中,从RelOptInfo的pathlist中找到代价最小的路径)
注:RelOptInfo数据结构由make_one_rel()函数创建,并存储在PlannerInfo数据结构的simple_rel_array字段中
4、通过plannodes.h文件中的PlannedStmt结构按照最小代价的路径生成一棵计划树

五、执行器按照计划树从下而上执行,每个计划节点都有对应的函数执行对应的操作。通过缓冲区管理器访问表或索引,使用backend进程的内存(work_mem,temp_buffer)等,必要时还会生成临时文件,最后把结果返回给客户端

posted @ 2025-12-10 11:39  夜说  阅读(41)  评论(0)    收藏  举报