点击查看代码
客户端发起SQL语句,postmaster进程fork一个backend进程来对接(SQL语句会依次经过backed进程里面的解析器,分析器,重写器,计划器,执行器),最终返回处理的结果。
一、一条sql语句(也就是一个字符串)会通过parsenode.h文件中的SelectStmt结构生成一颗语法解析树(这个阶段只会检查语法,不会检查语义)。
二、分析器接收解析树,通过parsenode.h文件中的Query结构生成一颗查询树(这个阶段会检查语义,例如表是否存在,字段是否存在)。
三、重写器会根据规则系统(pg_rule里面的规则)对查询树进行改写,生成一个新的查询树。
四、计划器获取上面的查询树进行以下三个步骤:
1、预处理(例如2+2直接改为4,not(not a)直接改为a等操作)
2、对所有可能的路径进行代价估算并找到代价最小的路径(创建一个RelOptInfo数据结构来存储访问路径及代价,估计所有路径的代价并将访问路径添加到RelOptInfo数据结构中,从RelOptInfo的pathlist中找到代价最小的路径)
3、通过plannodes.h文件中的PlannedStmt结构按照最小代价的路径生成一棵计划树
五、执行器会通过缓冲区管理器和存储管理器访问表或索引,使用backend进程的内存(work_mem,temp_buffer)等,必要时还会生成临时文件,最后把结果返回给客户端。