我給PostgreSQL的源代碼加入了調試信息以后,會有如下表現:
我執行Prepare:
postgres=# prepare s(int) as select * from tst01 t where id < $1; PREPARE postgres=#
背后的反應:
** In PostgresMain In exec_simple_query loop for parsetree_list++++++++++++++++++++++++++Before pg_plan_queries ***************In pg_plan_queries -------start ................In pg_plan_queries...query->commandType == CMD_UTILITY ***************In pg_plan_queries -------end In exec_simple_query loop for parsetree_list++++++++++++++++++++++++++After pg_plan_queries ...In exec_simple_query....Before PortalRun .....In PortalRun ------------start .......In PortalRunUtility ---------------start .........In ProcessUtility----Start .........In ProcessUtility----End .......In PortalRunUtility ---------------end .....In PortalRun ------------end ...In exec_simple_query....After PortalRun
接着執行 Execute:
postgres=# execute s(2); id ---- 1 (1 row) postgres=#
背后的反應:
In exec_simple_query loop for parsetree_list++++++++++++++++++++++++++Before pg_plan_queries ***************In pg_plan_queries -------start ................In pg_plan_queries...query->commandType == CMD_UTILITY ***************In pg_plan_queries -------end In exec_simple_query loop for parsetree_list++++++++++++++++++++++++++After pg_plan_queries ...In exec_simple_query....Before PortalRun .....In PortalRun ------------start xxxxxxIn FillPortalStore ...........start .......In PortalRunUtility ---------------start .........In ProcessUtility----Start ..........In standard_ProcessUtility ... Before ExecuteQuery xxxxxxxxxxxIn ExecuteQuery--------start ++++++++++++In GetCachedPlan ........start .............In BuildCachedPlan, Before pg_plan_queries ***************In pg_plan_queries -------start ................In pg_plan_queries...query->commandType != CMD_UTILITY ..................In pg_plan_query........start *******************In planner ........start ___________________In standard_planner........start ********************In subquery_planner........start ++++++++++++++++++++++In grouping_planner......start ************************In query_planner......start ........................In make_one_rel......start ...........................In set_base_rel_pathlists......start -----------------------------In set_rel_pathlist......start ******************************In set_plain_rel_pathlist......start -------------------------------Before add_path of seqscan -------------------------------After add_path of seqscan -------------------------------Before create_index_paths -------------------------------After create_index_path -------------------------------Before create_tidscan_paths -------------------------------After create_tidscan_paths -------------------------------Before set_cheapest -------------------------------After set_cheapest ******************************In set_plain_rel_pathlist......end -----------------------------In set_rel_pathlist......end ...........................In set_base_rel_pathlists......end ........................In make_one_rel......end ************************In query_planner......end ++++++++++++++++++++++In grouping_planner......end ********************In subquery_planner........end ___________________In standard_planner........end *******************In planner ........end ..................In pg_plan_query........end ***************In pg_plan_queries -------end .............In BuildCachedPlan, After pg_plan_queries ++++++++++++In GetCachedPlan ........end .....In PortalRun ------------start .....In PortalRun ------------end xxxxxxxxxxxIn ExecuteQuery--------end ..........In standard_ProcessUtility ... After ExecuteQuery .........In ProcessUtility----End .......In PortalRunUtility ---------------end xxxxxxIn FillPortalStore ...........end .....In PortalRun ------------end ...In exec_simple_query....After PortalRun
按照對過去版本的認識,應當是PortalRun的時候單純執行計划。
但是preapre....execute 方式,把它破壞了。
可以看到,prepare時候,不進行path的生成。
execute 的時候,在PortalRun的階段,通過 ExecuteQuery->GetCachedPlan->BuildCachedPlan,
來生成path和確定plan。
不過要注意到一點是,我所執行的上述的例子中,並沒有導致 param_info 非空。
可以說,這種針對單一表的preapre execute,是把執行計划的生成推后了,但是並不等於它就是 Parameterized Path。