千家信息网

PostgreSQL中PlannedStmt结构的日志分析

发表于:2025-01-25 作者:千家信息网编辑
千家信息网最后更新 2025年01月25日,这篇文章主要介绍了PostgreSQL中PlannedStmt结构的日志分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。APPEND
千家信息网最后更新 2025年01月25日PostgreSQL中PlannedStmt结构的日志分析

这篇文章主要介绍了PostgreSQL中PlannedStmt结构的日志分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

APPEND->appendplans

APPEND->appendplans是链表结构,有2个元素,每个元素的类型为T_NESTLOOP(内嵌循环),通常的信息与其他节点类型类似,重点是lefttree和righttree均不为空,jointype为0表示INNER_JOIN

LIMIT->SORT->APPEND->appendplans->head
lefttree
进入第一个元素的左树

              :lefttree                   {SEQSCAN /T_SEQSCAN类型的Node,顺序扫描                  :startup_cost 0.00                   :total_cost 12.00                   :plan_rows 1 //涉及的行数                  :plan_width 256 //平均行宽                  :parallel_aware false                   :parallel_safe true                   :plan_node_id 5 //Plan id                  :targetlist (...) //省略                  :qual (                     {OPEXPR                      :opno 98  //PG_OPERATOR OID of the operator,texteq字符串相等                     :opfuncid 67 //PG_PROC OID of underlying function,texteq字符串相等                     :opresulttype 16 //PG_TYPE OID of result value,bool值                     :opretset false                      :opcollid 0 //pg_collation                     :inputcollid 100 //输入的collation(default)                     :args (//参数,链表类型                        {RELABELTYPE //第1个参数为RelabelType类型                        :arg //指向Expr的指针,实际类型为VAR                           {VAR //第                           :varno 4 //在rtable中处于第4个位置的RTE                           :varattno 2 //属性编号                           :vartype 1043 //类型,pg_type OID,varchar                           :vartypmod 14                            :varcollid 100                            :varlevelsup 0                            :varnoold 4 //原始的varno                           :varoattno 2 //原始的varattno                           :location 110//token位置(在SQL语句中)                           }                        :resulttype 25                         :resulttypmod -1                         :resultcollid 100                         :relabelformat 2                         :location -1                        }                        {CONST //第2个参数为Const类型                        :consttype 25 //pg_type OID                        :consttypmod -1 //                        :constcollid 100 //                        :constlen -1                         :constbyval false //传值?如为false,则constvalue中的前4个字节为value的说明,在这个案例中,为32(即2的4次方),从第5个字节开始,长度为4的字符串                        :constisnull false                         :location 205 //token所在位置                        :constvalue 8 [ 32 0 0 0 49 48 48 49 ]//即字符串"1001"                        }                     )                     :location -1                     }                  )                  :lefttree <> //左树为空                  :righttree <> //右树为空                  :initPlan <> //无初始化Plan                  :extParam (b)                  :allParam (b)                  :scanrelid 4 //扫描第4号RTE                  }

rigthtree
进入第一个元素的右树

               :righttree                   {HASHJOIN //NestLoop右树节点类型是HashJoin(t_grxx join t_jfxx)                  :startup_cost 16.15                   :total_cost 36.12                   :plan_rows 7 //涉及的行数                  :plan_width 180 //平均行大小                  :parallel_aware false                   :parallel_safe true                   :plan_node_id 6 //计划节点id                  :targetlist (...) //投影列,省略                  :qual <> //表达式                  :lefttree //左树,暂时折叠                     {...}                  :righttree //右树,暂时折叠                     {...}                  :initPlan <> //初始化Plan                  :extParam (b)                  :allParam (b)                  :jointype 0 //INNER_JOIN                  :inner_unique false //非唯一inner join                  :joinqual <>                   :hashclauses (//hash信息,类型为OpExpr                     {OPEXPR                      :opno 98 //pg_operator Oid,"=",texteq                     :opfuncid 67 //pg_proc Oid,texteq                     :opresulttype 16                      :opretset false                      :opcollid 0 //default collation                     :inputcollid 100                      :args (//参数链表                        {RELABELTYPE//第1个元素 RelabelType                        :arg                            {VAR //VAR类型                           :varno 65001 //TODO                           :varattno 1 //第1列                           :vartype 1043 //字符串,varchar                           :vartypmod 14                            :varcollid 100                            :varlevelsup 0                            :varnoold 7 //原varno,7号RTE,即t_jfxx                           :varoattno 1 //原属性no                           :location 171//SQL语句中的token位置                           }                        :resulttype 25                         :resulttypmod -1                         :resultcollid 100                         :relabelformat 2                         :location -1                        }                        {RELABELTYPE //第1个元素 RelabelType                        :arg                            {VAR //VAR类型                           :varno 65000                            :varattno 1                            :vartype 1043                            :vartypmod 14                            :varcollid 100                            :varlevelsup 0                            :varnoold 5 //5号RTE,即t_grxx                           :varoattno 2 //2号属性                           :location 157                           }                        :resulttype 25                         :resulttypmod -1                         :resultcollid 100                         :relabelformat 2                         :location -1                        }                     )                     :location -1                     }                  )                  }               :initPlan <> //无初始化Plan               :extParam (b)               :allParam (b)               :jointype 0 //INNER_JOIN               :inner_unique false                :joinqual <>                :nestParams <>

下面考察HashJoin的左树和右树,首先看左树
...head(Plan)->righttree(HashJoin)->lefttree

                  :lefttree                      {SEQSCAN //顺序扫描                     :startup_cost 0.00                      :total_cost 17.20                      :plan_rows 720                      :plan_width 84                      :parallel_aware false                      :parallel_safe true                      :plan_node_id 7 //计划id                     :targetlist (...)                     :qual <>                      :lefttree <>                      :righttree <>                      :initPlan <>                      :extParam (b)                     :allParam (b)                     :scanrelid 7//编号为7的RTE即t_jfxx                     }

再看HashJoin右树
...head(Plan)->righttree(HashJoin)->righttree

                  :righttree                      {HASH //Hash操作(创建Hash表)                     :startup_cost 16.12                      :total_cost 16.12                      :plan_rows 2 //涉及2行                     :plan_width 134                      :parallel_aware false                      :parallel_safe true                      :plan_node_id 8                      :targetlist (...)                     :qual <>                      :lefttree //左树也是一个Plan                        {SEQSCAN //左树为顺序扫描                        :startup_cost 0.00                         :total_cost 16.12                         :plan_rows 2                         :plan_width 134                         :parallel_aware false                         :parallel_safe true                         :plan_node_id 9                         :targetlist (...)                        :qual (                           {OPEXPR //OpExpr类型                           :opno 98                            :opfuncid 67                            :opresulttype 16                            :opretset false                            :opcollid 0                            :inputcollid 100                            :args (                              {RELABELTYPE                               :arg                                  {VAR                                  :varno 5 //5号RTE,即t_grxx                                 :varattno 1 //第1个列,即dwbh                                 :vartype 1043                                  :vartypmod 14                                  :varcollid 100                                  :varlevelsup 0                                  :varnoold 5                                  :varoattno 1                                  :location 124                                 }                              :resulttype 25                               :resulttypmod -1                               :resultcollid 100                               :relabelformat 2                               :location -1                              }                              {CONST                               :consttype 25                               :consttypmod -1                               :constcollid 100                               :constlen -1                               :constbyval false //非参数传递                              :constisnull false                               :location 205                               :constvalue 8 [ 32 0 0 0 49 48 48 49 ]//字符串"1001"                              }                           )                           :location -1                           }                        )                        :lefttree <> //子左树的左树为空                        :righttree <> //子左树的右树为空                        :initPlan <>                         :extParam (b)                        :allParam (b)                        :scanrelid 5//扫描的RTE,5号即t_grxx                        }                     :righttree <> //右树为空                     :initPlan <>                      :extParam (b)                     :allParam (b)                     :skewTable 16397 //HashJoin的表Oid                     :skewColumn 1 //列序号                     :skewInherit false                      :rows_total 0                     }

LIMIT->SORT->APPEND->appendplans->head->next

子查询中的第2个NestLoop参照LIMIT->SORT->APPEND->appendplans->head即可,条件变为dwbh="1002",其他与链表中的head元素无异,不再累述

三、小结

1、计划树结构:通过日志输出分析计划树结构;
2、重要的数据结构:RTE、Plan等。

四、附录

如何开启跟踪日志?postgresql.conf配置文件设置参数:

log_destination = 'csvlog'log_directory = 'pg_log' #与postgresql.conf文件在同一级目录log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'log_rotation_age = 2dlog_rotation_size = 100MB#debug_print_parse = on  #打印parse树debug_print_rewritten = on #打印parse rewrite树debug_print_plan = on #打印plan树debug_pretty_print = on #以pretty方式显示

感谢你能够认真阅读完这篇文章,希望小编分享的"PostgreSQL中PlannedStmt结构的日志分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0