1.查询规划模块总体概况
废话不多说,我先上图。下图大概的刻画了查询规划模块里主要的函数调用关系,当然啦,最下层只画到主处理函数,主处理函数内部的调用关系在介绍每个主处理函数的时候再细细的说吧。

我简单介绍下吧。exec_simple_query函数是负责查询处理的主函数,在进行查询规划之前,它已经调用了查询分析和查询重写模块。还记得上一篇博文的查询重写模块么?该模块返回的是重写后的查询树链表。这里exec_simple_query函数将重写后的查询树链表交给查询规划模块进一步处理。查询规划模块的入口函数是pg_plan_queries函数。
pg_plan_queries函数调用pg_plan_query函数对每一个查询进行处理并返回PlannedStmt(执行计划)结构体链表。这里要注意,查询规划模块只会对非UTILITY命令进行处理。
而在pg_plan_query函数里,实际是调用planner函数负责查询计划的生成。
planner函数调用standard_planner函数进入标准的查询规划处理流程。该函数接受查询树以及相关参数,返回PlannedStmt结构体,详细的结构如下:
-
typedef struct PlannedStmt { NodeTag type; CmdType commandType; /* select|insert|update|delete */ uint32 queryId; /* query identifier (copied from Query) */ bool hasReturning; /* is it insert|update|delete RETURNING? */ bool hasModifyingCTE; /* has insert|update|delete in WITH? */ bool canSetTag; /* do I set the command result tag? */ bool transientPlan; /* redo plan when TransactionXmin changes? */ struct Plan *planTree; /* tree of Plan nodes */ List *rtable; /* list of RangeTblEntry nodes */ /* rtable indexes of target relations for INSERT/UPDATE/DELETE */ List *resultRelations; /* integer list of RT indexes, or NIL */ Node *utilityStmt; /* non-null if this is DECLARE CURSOR */ List *subpla

本文深入解析了查询规划模块的工作原理,介绍了exec_simple_query、pg_plan_queries等关键函数的作用及调用流程,详细阐述了subquery_planner函数如何通过预处理、查询规划处理和清理计划树三个阶段生成查询计划。
最低0.47元/天 解锁文章
4294

被折叠的 条评论
为什么被折叠?



