PostgreSQL中分区表查询相关的重要数据结构有哪些
本篇内容介绍了“PostgreSQL中分区表查询相关的重要数据结构有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
一、数据结构RelOptInfo
RelOptInfo是规划器/优化器使用的关系信息结构体
在规划过程中已存在的基表或者是在关系运算过程中产生的中间关系或者是最终产生的关系,都使用RelOptInfo结构体进行封装表示.
查询分区表时该结构体中的part_scheme存储分区的schema,nparts存储分区数,boundinfo是分区边界信息,partition_qual是分区约束条件,part_rels是分区表中每个分区的每个分区的RelOptInfo,partexprs是分区键表达式,partitioned_child_rels是关系中未修剪(unpruned)分区的RT索引.unpruned是指查询分区表时,涉及的相关分区,比如 where c1 = 1 OR c1 = 2涉及的分区只有t_hash_partition_1和t_hash_partition_3,则在partitioned_child_rels中只有这两个分区的信息.
如何pruned,下节介绍
/*----------*RelOptInfo*Per-relationinformationforplanning/optimization*规划器/优化器使用的关系信息结构体**Forplanningpurposes,a"baserel"iseitheraplainrelation(atable)*ortheoutputofasub-SELECTorfunctionthatappearsintherangetable.*IneithercaseitisuniquelyidentifiedbyanRTindex.A"joinrel"*isthejoiningoftwoormorebaserels.Ajoinrelisidentifiedby*thesetofRTindexesforitscomponentbaserels.WecreateRelOptInfo*nodesforeachbaserelandjoinrel,andstoretheminthePlannerInfo's*simple_rel_arrayandjoin_rel_listrespectively.*出于计划目的,“baserel”要么是一个普通关系(表),*要么是出现在范围表中的子查询或函数的输出。*在这两种情况下,它都是由RT索引惟一标识的。*"joinrel"是两个或两个以上的baserels连接。*一个joinrel是由它的baserels的RT索引集标识。*我们为每个baserel和joinrel分别创建RelOptInfo节点,*并将它们分别存储在PlannerInfo的simple_rel_array和join_rel_list中。**Notethatthereisonlyonejoinrelforanygivensetofcomponent*baserels,nomatterwhatorderweassemblethemin;soanunordered*setistherightdatatypetoidentifyitwith.*请注意,对于任何给定的baserels,无论我们以何种顺序组合它们,*都只有一个连接件;因此,一个无序的集合正好是标识它的数据类型。**Wealsohave"otherrels",whicharelikebaserelsinthattheyreferto*singleRTindexes;buttheyarenotpartofthejointree,andaregiven*adifferentRelOptKindtoidentifythem.*Currentlytheonlykindofotherrelsarethosemadeformemberrelations*ofan"appendrelation",thatisaninheritancesetorUNIONALLsubquery.*AnappendrelationhasaparentRTEthatisabaserel,whichrepresents*theentireappendrelation.ThememberRTEsareotherrels.Theparent*ispresentinthequeryjointreebutthemembersarenot.Themember*RTEsandotherrelsareusedtoplanthescansoftheindividualtablesor*subqueriesoftheappendset;thentheparentbaserelisgivenAppend*and/orMergeAppendpathscomprisingthebestpathsfortheindividual*memberrels.(SeecommentsforAppendRelInfoformoreinformation.)*同时存在“otherrels”,类似于baserels,它们同样都指向单个RT索引;*但是它们不是join树的一部分,并且被赋予不同的RelOptKind来标识它们。*目前唯一的其他类型是那些为“appendrelation”的成员关系而创建的,*即继承集或UNIONALL子查询。*一个appendrelation有一个父RTE,它是一个基础rel,表示整个appendrelation。*其他成员RTEs是otherrel.。*父节点存在于查询的连接树中,但成员无需存储在连接树中。*成员RTEs和otherrels用于计划对appendset的单表或子查询的扫描;*然后给出parentbaserel的APPEND路径和/或MergeAppend路径,这些路径包含单个成员rels的最佳路径。*(更多信息请参见AppendRelInfo的注释。)**AtonetimewealsomadeotherrelstorepresentjoinRTEs,forusein*handlingjoinaliasVars.Currentlythisisnotneededbecausealljoin*aliasVarsareexpandedtonon-aliasedformduringpreprocess_expression.*曾经,还制作了其他的树来表示连接rte,用于处理连接别名Vars。*目前不需要这样做,因为在preprocess_expression期间,所有连接别名Vars都被扩展为非别名形式。**Wealsohaverelationsrepresentingjoinsbetweenchildrelationsof*differentpartitionedtables.Theserelationsarenotaddedto*join_rel_levellistsastheyarenotjoineddirectlybythedynamic*programmingalgorithm.*还有表示不同分区表的子关系之间的连接的关系。*这些关系不会添加到join_rel_level链表中,因为动态规划算法不会直接连接它们。**ThereisalsoaRelOptKindfor"upper"relations,whichareRelOptInfos*thatdescribepost-scan/joinprocessingsteps,suchasaggregation.*ManyofthefieldsintheseRelOptInfosaremeaningless,buttheirPath*fieldsalwaysholdPathsshowingwaystodothatprocessingstep.*还有一种RelOptKind表示“upper”关系,*即描述扫描/连接后处理步骤(如聚合)的RelOptInfos。*这些RelOptInfos中的许多字段都是没有意义的,*但是它们的Path字段总是包含显示执行该处理步骤的路径。**Lastly,thereisaRelOptKindfor"dead"relations,whicharebaserels*thatwehaveprovenwedon'tneedtojoinafterall.*最后,还有一种关系是“DEAD”的关系,在规划期间已经证明不需要把此关系加入连接。**Partsofthisdatastructurearespecifictovariousscanandjoin*mechanisms.Itdidn'tseemworthcreatingnewnodetypesforthem.*该数据结构的某些部分特定于各种扫描和连接机制。*但似乎不值得为它们创建新的节点类型。**relids-Setofbase-relationidentifiers;itisabaserelation*ifthereisjustone,ajoinrelationifmorethanone*relids-基础关系标识符的集合;如只有一个则为基础关系,*如有多个则为连接关系*rows-estimatednumberoftuplesintherelationafterrestriction*clauseshavebeenapplied(ie,outputrowsofaplanforit)*rows-应用约束条件子句后关系中元组的估算数目(即计划的输出行数)*consider_startup-trueifthereisanyvalueinkeepingplainpathsfor*thisrelonthebasisofhavingcheapstartupcost*consider_startup-如果在具有低启动成本的基础上为这个rel保留访问路径有价值,则为真*consider_param_startup-thesameforparameterizedpaths*consider_param_startup-与parameterized访问路径一致*reltarget-DefaultPathoutputtlistforthisrel;normallycontains*VarandPlaceHolderVarnodesforthevaluesweneedto*outputfromthisrelation.*Listisinnoparticularorder,butallrelsofan*appendrelsetmustusecorrespondingorders.*NOTE:inanappendrelchildrelation,maycontain*arbitraryexpressionspulledupfromasubquery!*reltarget-该rel的默认路径输出投影列;通常会包含Var和PlaceHolderVar*pathlist-ListofPathnodes,oneforeachpotentiallyuseful*methodofgeneratingtherelation*访问路径节点链表,存储每一种可能有用的生成关系的方法*ppilist-ParamPathInfonodesforparameterizedPaths,ifany*参数化路径的ParamPathInfo节点(如果有的话)*cheapest_startup_path-thepathlistmemberwithloweststartupcost*(regardlessofordering)amongtheunparameterizedpaths;*orNULLifthereisnounparameterizedpath*在非参数化路径中启动成本最低(无论顺序如何)的路径链表成员;*如果没有非参数化路径,则为NULL*cheapest_total_path-thepathlistmemberwithlowesttotalcost*(regardlessofordering)amongtheunparameterizedpaths;*orifthereisnounparameterizedpath,thepathwithlowest*totalcostamongthepathswithminimumparameterization*在非参数化路径中总成本最低(无论顺序如何)的路径列表成员;*如果没有非参数化路径,则在参数化最少的路径中总成本最低的路径*cheapest_unique_path-forcachingcheapestpathtoproduceunique*(noduplicates)outputfromrelation;NULLifnotyetrequested*用于缓存最便宜的路径,以便从关系中产生唯一(无重复)输出;*如果无此要求,则为NULL*cheapest_parameterized_paths-bestpathsfortheirparameterizations;*alwaysincludescheapest_total_path,evenifthat'sunparameterized*参数化的最佳路径;总是包含cheapest_total_path,即使它是非参数化的*direct_lateral_relids-relsthisrelhasdirectLATERALreferencesto*该rel直接LATERAL依赖的rels*lateral_relids-requiredouterrelsforLATERAL,asaRelidsset*(includesbothdirectandindirectlateralreferences)*LATERAL所需的外部rels,作为Relids集合(包括直接和间接的侧向参考)**Iftherelationisabaserelationitwillhavethesefieldsset:*如果关系是一个基本关系,它将设置这些字段:*relid-RTEindex(thisisredundantwiththerelidsfield,but*isprovidedforconvenienceofaccess)*RTE索引(这对于relids字段来说是冗余的,但是为了方便访问而提供)*rtekind-copyofRTE'srtekindfield*RTE'srtekind字段的拷贝*min_attr,max_attr-rangeofvalidAttrNumbersforrel*关系有效AttrNumbers的范围(最大/最小编号)*attr_needed-arrayofbitmapsetsindicatingthehighestjoinrel*inwhicheachattributeisneeded;ifbit0issetthen*theattributeisneededaspartoffinaltargetlist*位图集数组,表示每个属性所需的最高层joinrel;*如果设置为0,则需要将该属性作为最终targetlist的一部分*attr_widths-cachespaceforper-attributewidthestimates;*zeromeansnotcomputedyet*用于每个属性宽度估计的缓存空间;0表示还没有计算*lateral_vars-lateralcross-referencesofrel,ifany(listof*VarsandPlaceHolderVars)*rel的lateral交叉参照,如果有的话(Vars和PlaceHolderVars链表)*lateral_referencers-relidsofrelsthatreferencethisonelaterally*(includesbothdirectandindirectlateralreferences)*lateral依赖此关系的relids(包括直接&间接lateral依赖)*indexlist-listofIndexOptInfonodesforrelation'sindexes*(alwaysNILifit'snotatable)*关系索引的IndexOptInfo节点链表(如果不是表,总是NIL)*pages-numberofdiskpagesinrelation(zeroifnotatable)*关系的磁盘页数(如不是表,则为0)*tuples-numberoftuplesinrelation(notconsideringrestrictions)*关系的元组数统计(还没有考虑约束条件)*allvisfrac-fractionofdiskpagesthataremarkedall-visible*标记为all-visible的磁盘页数比例*subroot-PlannerInfoforsubquery(NULLifit'snotasubquery)*用于子查询的PlannerInfo(如果不是子查询,则为NULL)*subplan_params-listofPlannerParamItemstobepassedtosubquery*要传递给子查询的PlannerParamItems的链表*Note:forasubquery,tuplesandsubrootarenotsetimmediately*uponcreationoftheRelOptInfoobject;theyarefilledinwhen*set_subquery_pathlistprocessestheobject.*对于子查询,元组和subroot不会在创建RelOptInfo对象时立即设置;*它们是在set_subquery_pathlist处理对象时填充的。**Forotherrelsthatareappendrelmembers,thesefieldsarefilled*injustasforabaserel,exceptwedon'tbotherwithlateral_vars.*对于其他appendrel成员,这些字段就像baserels一样被填充,*除了我们不关心的lateral_vars。**Iftherelationiseitheraforeigntableorajoinofforeigntablesthat*allbelongtothesameforeignserverandareassignedtothesameuserto*checkaccesspermissionsas(cfcheckAsUser),thesefieldswillbeset:*如果关系是一个外表或一个外表的连接,这些表都属于相同的外服务器*并被分配给相同的用户来检查访问权限(cfcheckAsUser),这些字段将被设置:**serverid-OIDofforeignserver,ifforeigntable(elseInvalidOid)*外部服务器的OID,如不为外部表则为InvalidOid*userid-OIDofusertocheckaccessas(InvalidOidmeanscurrentuser)*检查访问权限的用户OID(InvalidOid表示当前用户)*useridiscurrent-we'veassumedthatuseridequalscurrentuser*我们假设userid为当前用户*fdwroutine-functionhooksforFDW,ifforeigntable(elseNULL)*FDW的函数钩子,如不是外部表则为NULL*fdw_private-privatestateforFDW,ifforeigntable(elseNULL)*FDW的私有状态,不是外部表则为NULL**Twofieldsareusedtocacheknowledgeacquiredduringthejoinsearch*aboutwhetherthisrelisprovablyuniquewhenbeingjoinedtogivenother*relation(s),ie,itcanhaveatmostonerowmatchinganygivenrowfrom*thatjoinrelation.Currentlyweonlyattemptsuchproofs,andthusonly*populatethesefields,forbaserels;butsomedaytheymightbeusedfor*joinrelstoo:*下面的两个字段用于缓存在连接搜索过程中获取的信息,*这些信息是关于当这个rel被连接到给定的其他关系时是否被证明是唯一的,*也就是说,它最多只能有一行匹配来自该连接关系的任何给定行。*目前我们只尝试这样的证明,因此只填充这些字段,用于baserels;*但总有一天它们也可以被用来加入joinrels:**unique_for_rels-listofRelidsets,eachonebeingasetofother*relsforwhichthisonehasbeenprovenunique*Relid集合的链表,每一个都是一组otherrels,这些rels已经被证明是唯一的*non_unique_for_rels-listofRelidsets,eachonebeingasetof*otherrelsforwhichwehavetriedandfailedtoprove*thisoneunique*Relid集合的链表,每个集合都是otherrels,这些rels试图证明唯一的,但失败了**Thepresenceofthefollowingfieldsdependsontherestrictions*andjoinsthattherelationparticipatesin:*以下字段的存在取决于约束条件和关系所参与的连接:**baserestrictinfo-ListofRestrictInfonodes,containinginfoabout*eachnon-joinqualificationclauseinwhichthisrelation*participates(onlyusedforbaserels)*RestrictInfo节点链表,其中包含关于此关系参与的每个非连接限定子句的信息(仅用于基础rels)*baserestrictcost-Estimatedcostofevaluatingthebaserestrictinfo*clausesatasingletuple(onlyusedforbaserels)*在单个元组中解析baserestrictinfo子句的估算成本(仅用于基础rels)*baserestrict_min_security-Smallestsecurity_levelfoundamong*clausesinbaserestrictinfo*在baserestrictinfo子句中找到的最小security_level*joininfo-ListofRestrictInfonodes,containinginfoabouteach*joinclauseinwhichthisrelationparticipates(but*notethisexcludesclausesthatmightbederivablefrom*EquivalenceClasses)*RestrictInfo节点链表,其中包含关于此关系参与的每个连接条件子句的信息*(但请注意,这排除了可能从等价类派生的子句)*has_eclass_joins-flagthatEquivalenceClassjoinsarepossible*用于标记等价类连接是可能的**Note:KeepingarestrictinfolistintheRelOptInfoisusefulonlyfor*baserels,becauseforajoinrelthesetofclausesthataretreatedas*restrictclausesvariesdependingonwhichsub-relationswechoosetojoin.*(Forexample,ina3-base-reljoin,aclauserelatingrels1and2mustbe*treatedasarestrictclauseifwejoin{1}and{23}tomake{123};but*ifwejoin{12}and{3}thenthatclausewillbearestrictclausein{12}*andshouldnotbeprocessedagainatthelevelof{123}.)Therefore,*therestrictinfolistinthejoincaseappearsinindividualJoinPaths*(fieldjoinrestrictinfo),notintheparentrelation.Butit'sOKfor*theRelOptInfotostorethejoininfolist,becausethatisthesame*foragivenrelnomatterhowweformit.*注意:在RelOptInfo中保存一个restrictinfo链表只对基础rels有用,*因为对于一个joinrel,被视为限制子句的子句集会根据我们选择加入的子关系而变化。(例如,在一个3-base-rel连接中,如果我们加入{1}和{23}以生成{123},则与efs1和2相关的子句必须被视为限制性子句;但是如果我们加入{12}和{3},那么该子句将是{12}中的一个限制性子句,不应该在{123}的级别上再次处理)。因此,在join案例中,节流信息列表出现在单独的连接路径(字段join节流信息)中,而不是在父关系中。但是RelOptInfo可以存储joininfo列表,因为对于给定的rel,无论我们如何形成它都是一样的。**WestorebaserestrictcostintheRelOptInfo(forbaserelations)because*weknowwewillneeditatleastonce(topricethesequentialscan)*andmayneeditmultipletimestopriceindexscans.*我们将baserestrictcost存储在RelOptInfo(用于基本关系)中,*因为我们知道至少需要它一次(为顺序扫描计算成本),并且可能需要它多次来为索引扫描计算成本。**Iftherelationispartitioned,thesefieldswillbeset:*如果关系是分区表,会设置这些字段:**part_scheme-Partitioningschemeoftherelation*关系的分区schema*nparts-Numberofpartitions*关系的分区数*boundinfo-Partitionbounds*分区边界信息*partition_qual-Partitionconstraintifnottheroot*如非root,则该字段存储分区约束条件*part_rels-RelOptInfosforeachpartition*每个分区的RelOptInfos*partexprs,nullable_partexprs-Partitionkeyexpressions*分区键表达式*partitioned_child_rels-RTindexesofunprunedpartitionsof*thisrelationthatarepartitionedtables*themselves,inhierarchicalorder*关系中未修剪(unpruned)分区的RT索引,*这些分区本身就是分区表,按层次顺序排列**Note:Abaserelationalwayshasonlyonesetofpartitionkeys,butajoin*relationmayhaveasmanysetsofpartitionkeysasthenumberofrelations*beingjoined.partexprsandnullable_partexprsarearrayscontaining*part_scheme->partnattselementseach.Eachoftheseelementsisalistof*partitionkeyexpressions.Forabaserelationeachlistinpartexprs*containsonlyoneexpressionandnullable_partexprsisnotpopulated.Fora*joinrelation,partexprsandnullable_partexprscontainpartitionkey*expressionsfromnon-nullableandnullablerelationsresp.Listsatany*givenpositioninthosearraystogethercontainasmanyelementsasthe*numberofjoiningrelations.*注意:一个基本关系总是只有一组分区键,*但是连接关系的分区键可能与被连接的关系的数量一样多。*partexprs和nullable_partexp是分别包含part_scheme->partnatts元素的数组。*每个元素都是分区键表达式的链表。*对于基本关系,partexprs中的每个链表只包含一个表达式,*并且不填充nullable_partexprs。*对于连接关系,partexprs和nullable_partexprs包含来自非空和可空关系resp的分区键表达式。*这些数组中任意给定位置的链表包含的元素与连接关系的数量一样多。*----------*/typedefenumRelOptKind{RELOPT_BASEREL,//基本关系(如基表/子查询等)RELOPT_JOINREL,//连接产生的关系,要注意的是通过连接等方式产生的结果亦可以视为关系RELOPT_OTHER_MEMBER_REL,RELOPT_OTHER_JOINREL,RELOPT_UPPER_REL,//上层的关系RELOPT_OTHER_UPPER_REL,RELOPT_DEADREL}RelOptKind;/**Isthegivenrelationasimplerelationi.eabaseor"other"member*relation?*/#defineIS_SIMPLE_REL(rel)\((rel)->reloptkind==RELOPT_BASEREL||\(rel)->reloptkind==RELOPT_OTHER_MEMBER_REL)/*Isthegivenrelationajoinrelation?*/#defineIS_JOIN_REL(rel)\((rel)->reloptkind==RELOPT_JOINREL||\(rel)->reloptkind==RELOPT_OTHER_JOINREL)/*Isthegivenrelationanupperrelation?*/#defineIS_UPPER_REL(rel)\((rel)->reloptkind==RELOPT_UPPER_REL||\(rel)->reloptkind==RELOPT_OTHER_UPPER_REL)/*Isthegivenrelationan"other"relation?*/#defineIS_OTHER_REL(rel)\((rel)->reloptkind==RELOPT_OTHER_MEMBER_REL||\(rel)->reloptkind==RELOPT_OTHER_JOINREL||\(rel)->reloptkind==RELOPT_OTHER_UPPER_REL)typedefstructRelOptInfo{//节点标识NodeTagtype;//RelOpt类型RelOptKindreloptkind;/*allrelationsincludedinthisRelOptInfo*///所有关系都有的属性//Relids(rtindex)集合Relidsrelids;/*setofbaserelids(rangetableindexes)*//*sizeestimatesgeneratedbyplanner*///规划器生成的大小估算//结果元组的估算数量doublerows;/*estimatednumberofresulttuples*//*per-relationplannercontrolflags*///规划器使用的每个关系的控制标记//是否考虑启动成本?是,需要保留启动成本低的路径boolconsider_startup;/*keepcheap-startup-costpaths?*///是否考虑参数化?的路径boolconsider_param_startup;/*dittoforparameterizedpaths?*///是否考虑并行处理路径boolconsider_parallel;/*considerparallelpaths?*//*defaultresulttargetlistforPathsscanningthisrelation*///扫描该Relation时默认的结果投影列//Vars/Exprs,成本,行平均大小链表structPathTarget*reltarget;/*listofVars/Exprs,cost,width*//*materializationinformation*///物化信息//访问路径链表List*pathlist;/*Pathstructures*///路径链表中的ParamPathInfos链表List*ppilist;/*ParamPathInfosusedinpathlist*///并行部分路径List*partial_pathlist;/*partialPaths*///启动代价最低的路径structPath*cheapest_startup_path;//整体代价最低的路径structPath*cheapest_total_path;//获取唯一值代价最低的路径structPath*cheapest_unique_path;//参数化代价最低的路径List*cheapest_parameterized_paths;/*parameterizationinformationneededforbothbaserelsandjoinrels*//*(seealsolateral_varsandlateral_referencers)*///基本通道和连接通道都需要参数化信息//(参考lateral_vars和lateral_referencers)//使用lateral语法,需依赖的RelidsRelidsdirect_lateral_relids;/*relsdirectlylaterallyreferenced*///rel的最小化参数信息Relidslateral_relids;/*minimumparameterizationofrel*//*informationaboutabaserel(notsetforjoinrels!)*///reloptkind=RELOPT_BASEREL时使用的数据结构//relidIndexrelid;/*RelationID*///表空间Oidreltablespace;/*containingtablespace*///类型:基表?子查询?还是函数等等?RTEKindrtekind;/*RELATION,SUBQUERY,FUNCTION,etc*///最小的属性编号AttrNumbermin_attr;/*smallestattrnoofrel(often<0)*///最大的属性编号AttrNumbermax_attr;/*largestattrnoofrel*///属性数组Relids*attr_needed;/*arrayindexed[min_attr..max_attr]*///属性宽度int32*attr_widths;/*arrayindexed[min_attr..max_attr]*///关系依赖的LATERALVars/PHVsList*lateral_vars;/*LATERALVarsandPHVsreferencedbyrel*///依赖该关系的RelidsRelidslateral_referencers;/*relsthatreferencemelaterally*///该关系的IndexOptInfo链表List*indexlist;/*listofIndexOptInfo*///统计信息链表List*statlist;/*listofStatisticExtInfo*///块数BlockNumberpages;/*sizeestimatesderivedfrompg_class*///元组数doubletuples;/**///doubleallvisfrac;/*?*///如为子查询,存储子查询的rootPlannerInfo*subroot;/*ifsubquery*///如为子查询,存储子查询的参数List*subplan_params;/*ifsubquery*///并行执行,需要多少个workers?intrel_parallel_workers;/*wantednumberofparallelworkers*//*Informationaboutforeigntablesandforeignjoins*///FWD相关信息//表或连接的服务器标识符Oidserverid;/*identifiesserverforthetableorjoin*///用户id标识Oiduserid;/*identifiesusertocheckaccessas*///对于当前用户来说,连接才是有效的booluseridiscurrent;/*joinisonlyvalidforcurrentuser*//*use"structFdwRoutine"toavoidincludingfdwapi.hhere*///使用结构体FdwRoutine,避免包含头文件fdwapi.hstructFdwRoutine*fdwroutine;void*fdw_private;/*cachespaceforrememberingifwehaveproventhisrelationunique*///如果已证明该关系是唯一的,那么这些是用于缓存这些信息的字段//已知的,可保证唯一的Relids链表List*unique_for_rels;/*knownuniquefortheseotherrelid*set(s)*///已知的,不唯一的Relids链表List*non_unique_for_rels;/*knownnotuniquefortheseset(s)*//*usedbyvariousscansandjoins:*///用于各种扫描和连接//如为基本关系,存储约束条件链表List*baserestrictinfo;/*RestrictInfostructures(ifbaserel)*///解析约束表达式的成本?QualCostbaserestrictcost;/*costofevaluatingtheabove*///最低安全等级Indexbaserestrict_min_security;/*minsecurity_levelfoundin*baserestrictinfo*///连接语句的约束条件信息List*joininfo;/*RestrictInfostructuresforjoinclauses*involvingthisrel*///是否存在等价类连接?boolhas_eclass_joins;/*Tmeansjoininfoisincomplete*//*usedbypartitionwisejoins:*///partitionwise连接使用的字段//是否考虑使用partitionwisejoin?boolconsider_partitionwise_join;/*considerpartitionwise*joinpaths?(if*partitionedrel)*///最高层的父关系RelidsRelidstop_parent_relids;/*Relidsoftopmostparents(if"other"*rel)*//*usedforpartitionedrelations*///分区表使用//分区的schemaPartitionSchemepart_scheme;/*Partitioningscheme.*///分区数intnparts;/*numberofpartitions*///分区边界信息structPartitionBoundInfoData*boundinfo;/*Partitionbounds*///分区约束List*partition_qual;/*partitionconstraint*///分区的RelOptInfo数组structRelOptInfo**part_rels;/*ArrayofRelOptInfosofpartitions,*storedinthesameorderofbounds*///非空分区键表达式链表List**partexprs;/*Non-nullablepartitionkeyexpressions.*///可为空的分区键表达式List**nullable_partexprs;/*Nullablepartitionkeyexpressions.*///分区子表RTIndexes链表List*partitioned_child_rels;/*ListofRTindexes.*/}RelOptInfo;
AppendRelInfo
Append-relation信息.
当我们将可继承表(分区表)或UNION-ALL子查询展开为“追加关系”(本质上是子RTE的链表)时,为每个子RTE构建一个AppendRelInfo。
AppendRelInfos链表指示在展开父节点时必须包含哪些子rte,每个节点具有将引用父节点的Vars转换为引用该子节点的Vars所需的所有信息。
/**Append-relationinfo.*Append-relation信息.**WhenweexpandaninheritabletableoraUNION-ALLsubselectintoan*"appendrelation"(essentially,alistofchildRTEs),webuildan*AppendRelInfoforeachchildRTE.ThelistofAppendRelInfosindicates*whichchildRTEsmustbeincludedwhenexpandingtheparent,andeachnode*carriesinformationneededtotranslateVarsreferencingtheparentinto*Varsreferencingthatchild.*当我们将可继承表(分区表)或UNION-ALL子查询展开为“追加关系”(本质上是子RTE的链表)时,*为每个子RTE构建一个AppendRelInfo。*AppendRelInfos链表指示在展开父节点时必须包含哪些子rte,*每个节点具有将引用父节点的Vars转换为引用该子节点的Vars所需的所有信息。**ThesestructsarekeptinthePlannerInfonode'sappend_rel_list.*Notethatwejustthrowallthestructsintoonelist,andscanthe*wholelistwhendesiringtoexpandanyoneparent.Wecouldhaveused*amorecomplexdatastructure(eg,onelistperparent),butthiswould*behardertoupdateduringoperationssuchaspullingupsubqueries,*andnotreallyanyeasiertoscan.Consideringthattypicalqueries*willnothavemanydifferentappendparents,itdoesn'tseemworthwhile*tocomplicatethings.*这些结构体保存在PlannerInfo节点的append_rel_list中。*注意,只是将所有的结构体放入一个链表中,并在希望展开任何父类时扫描整个链表。*本可以使用更复杂的数据结构(例如,每个父节点一个列表),*但是在提取子查询之类的操作中更新它会更困难,*而且实际上也不会更容易扫描。*考虑到典型的查询不会有很多不同的附加项,因此似乎不值得将事情复杂化。**Note:aftercompletionoftheplannerprepphase,anygivenRTEisan*appendparenthavingentriesinappend_rel_listifandonlyifits*"inh"flagisset.Weclear"inh"forplaintablesthatturnoutnot*tohaveinheritancechildren,and(inanabuseoftheoriginalmeaning*oftheflag)weset"inh"forsubqueryRTEsthatturnouttobe*flattenableUNIONALLqueries.Thisletsusavoiduselesssearches*ofappend_rel_list.*注意:计划准备阶段完成后,*当且仅当它的“inh”标志已设置时,给定的RTE是一个appendparent在append_rel_list中的一个条目。*我们为没有child的平面表清除“inh”标记,*同时(有滥用标记的嫌疑)为UNIONALL查询中的子查询RTEs设置“inh”标记。*这样可以避免对append_rel_list进行无用的搜索。**Note:thedatastructureassumesthatappend-relmembersaresingle*baserels.ThisisOKforinheritance,butitpreventsusfrompulling*upaUNIONALLmembersubqueryifitcontainsajoin.Whilethatcould*befixedwithamorecomplexdatastructure,atpresentthere'snotmuch*pointbecausenoimprovementintheplancouldresult.*注意:数据结构假定附加的rel成员是独立的baserels。*这对于继承来说是可以的,但是如果UNIONALLmember子查询包含一个join,*那么它将阻止我们提取UNIONALLmember子查询。*虽然可以用更复杂的数据结构解决这个问题,但目前没有太大意义,因为该计划可能不会有任何改进。*/typedefstructAppendRelInfo{NodeTagtype;/**Thesefieldsuniquelyidentifythisappendrelationship.Therecanbe*(infact,alwaysshouldbe)multipleAppendRelInfosforthesame*parent_relid,butnevermorethanoneperchild_relid,sinceagiven*RTEcannotbeachildofmorethanoneappendparent.*这些字段惟一地标识这个appendrelationship。*对于同一个parent_relid可以有(实际上应该总是)多个AppendRelInfos,*但是每个child_relid不能有多个AppendRelInfos,*因为给定的RTE不能是多个appendparent的子节点。*/Indexparent_relid;/*parentrel的RT索引;RTindexofappendparentrel*/Indexchild_relid;/*childrel的RT索引;RTindexofappendchildrel*//**Foraninheritanceappendrel,theparentandchildarebothregular*relations,andwestoretheirrowtypeOIDshereforuseintranslating*whole-rowVars.ForaUNION-ALLappendrel,theparentandchildare*bothsubquerieswithnonamedrowtype,andwestoreInvalidOidhere.*对于继承appendrel,父类和子类都是普通关系,*我们将它们的rowtypeOIDs存储在这里,用于转换whole-rowVars。*对于UNION-ALLappendrel,父查询和子查询都是没有指定行类型的子查询,*我们在这里存储InvalidOid。*/Oidparent_reltype;/*OIDofparent'scompositetype*/Oidchild_reltype;/*OIDofchild'scompositetype*//**TheN'thelementofthislistisaVarorexpressionrepresentingthe*childcolumncorrespondingtotheN'thcolumnoftheparent.Thisis*usedtotranslateVarsreferencingtheparentrelintoreferencesto*thechild.AlistelementisNULLifitcorrespondstoadropped*columnoftheparent(thisisonlypossibleforinheritancecases,not*UNIONALL).ThelistelementsarealwayssimpleVarsforinheritance*cases,butcanbearbitraryexpressionsinUNIONALLcases.*这个列表的第N个元素是一个Var或表达式,表示与父元素的第N列对应的子列。*这用于将引用parentrel的Vars转换为对子rel的引用。*如果链表元素与父元素的已删除列相对应,则该元素为NULL*(这只适用于继承情况,而不是UNIONALL)。*对于继承情况,链表元素总是简单的变量,但是可以是UNIONALL情况下的任意表达式。**Noticeweonlystoreentriesforusercolumns(attno>0).Whole-row*Varsarespecial-cased,andsystemcolumns(attno<0)neednospecial*translationsincetheirattnosarethesameforalltables.*注意,我们只存储用户列的条目(attno>0)。*Whole-rowVars是大小写敏感的,系统列(attno<0)不需要特别的转换,*因为它们的attno对所有表都是相同的。**Caution:theVarshavevarlevelsup=0.Becarefultoadjustasneeded*whencopyingintoasubquery.*注意:Vars的varlevelsup=0。*在将数据复制到子查询时,要注意根据需要进行调整。*///child'sVars中的表达式List*translated_vars;/*Expressionsinthechild'sVars*//**Westoretheparenttable'sOIDhereforinheritance,orInvalidOidfor*UNIONALL.Thisisonlyneededtohelpingeneratingerrormessagesif*anattemptismadetoreferenceadroppedparentcolumn.*我们将父表的OID存储在这里用于继承,*如为UNIONALL,则这里存储的是InvalidOid。*只有在试图引用已删除的父列时,才需要这样做来帮助生成错误消息。*/Oidparent_reloid;/*OIDofparentrelation*/}AppendRelInfo;
PlannerInfo
该数据结构用于存储查询语句在规划/优化过程中的相关信息
/*----------*PlannerInfo*Per-queryinformationforplanning/optimization*用于规划/优化的每个查询信息**Thisstructisconventionallycalled"root"inalltheplannerroutines.*Itholdslinkstoalloftheplanner'sworkingstate,inadditiontothe*originalQuery.Notethatatpresenttheplannerextensivelymodifies*thepassed-inQuerydatastructure;somedaythatshouldstop.*在所有计划程序例程中,这个结构通常称为“root”。*除了原始查询之外,它还保存到所有计划器工作状态的链接。*注意,目前计划器会毫无节制的修改传入的查询数据结构,相信总有一天这种情况会停止的。*----------*/structAppendRelInfo;typedefstructPlannerInfo{NodeTagtype;//Node标识//查询树Query*parse;/*theQuerybeingplanned*///当前的planner全局信息PlannerGlobal*glob;/*globalinfoforcurrentplannerrun*///查询层次,1标识最高层Indexquery_level;/*1attheoutermostQuery*///如为子计划,则这里存储父计划器指针,NULL标识最高层structPlannerInfo*parent_root;/*NULLatoutermostQuery*//**plan_paramscontainstheexpressionsthatthisquerylevelneedsto*makeavailabletoalowerquerylevelthatiscurrentlybeingplanned.*outer_paramscontainstheparamIdsofPARAM_EXECParamsthatouter*querylevelswillmakeavailabletothisquerylevel.*plan_params包含该查询级别需要提供给当前计划的较低查询级别的表达式。*outer_params包含PARAM_EXECParams的参数,外部查询级别将使该查询级别可用这些参数。*/List*plan_params;/*listofPlannerParamItems,seebelow*/Bitmapset*outer_params;/**simple_rel_arrayholdspointersto"baserels"and"otherrels"(see*commentsforRelOptInfoformoreinfo).Itisindexedbyrangetable*index(soentry0isalwayswasted).EntriescanbeNULLwhenanRTE*doesnotcorrespondtoabaserelation,suchasajoinRTEoran*unreferencedviewRTE;oriftheRelOptInfohasn'tbeenmadeyet.*simple_rel_array保存指向“baserels”和“otherrels”的指针*(有关RelOptInfo的更多信息,请参见注释)。*它由可范围表索引建立索引(因此条目0总是被浪费)。*当RTE与基本关系(如JOINRTE或未被引用的视图RTE时)不相对应*或者如果RelOptInfo还没有生成,条目可以为NULL。*///RelOptInfo数组,存储"baserels",比如基表/子查询等.//该数组与RTE的顺序一一对应,而且是从1开始,因此[0]无用*/structRelOptInfo**simple_rel_array;/*All1-relRelOptInfos*/intsimple_rel_array_size;/*数组大小,allocatedsizeofarray*//**simple_rte_arrayisthesamelengthassimple_rel_arrayandholds*pointerstotheassociatedrangetableentries.Thisletsusavoid*rt_fetch(),whichcanbeabitslowoncelargeinheritancesetshave*beenexpanded.*simple_rte_array的长度与simple_rel_array相同,*并保存指向相应范围表条目的指针。*这使我们可以避免执行rt_fetch(),因为一旦扩展了大型继承集,rt_fetch()可能会有点慢。*///RTE数组RangeTblEntry**simple_rte_array;/*rangetableasanarray*//**append_rel_arrayisthesamelengthastheabovearrays,andholds*pointerstothecorrespondingAppendRelInfoentryindexedby*child_relid,orNULLifnone.Thearrayitselfisnotallocatedif*append_rel_listisempty.*append_rel_array与上述数组的长度相同,*并保存指向对应的AppendRelInfo条目的指针,该条目由child_relid索引,*如果没有索引则为NULL。*如果append_rel_list为空,则不分配数组本身。*///处理集合操作如UNIONALL时使用和分区表时使用structAppendRelInfo**append_rel_array;/**all_baserelsisaRelidssetofallbaserelids(butnot"other"*relids)inthequery;thatis,theRelidsidentifierofthefinaljoin*weneedtoform.Thisiscomputedinmake_one_rel,justbeforewe*startmakingPaths.*all_baserels是查询中所有baserelids(但不是“other”relids)的一个Relids集合;*也就是说,这是需要形成的最终连接的Relids标识符。*这是在开始创建路径之前在make_one_rel中计算的。*/Relidsall_baserels;//"baserels"/**nullable_baserelsisaRelidssetofbaserelidsthatarenullableby*someouterjoininthejointree;thesearerelsthatarepotentially*nullablebelowtheWHEREclause,SELECTtargetlist,etc.Thisis*computedindeconstruct_jointree.*nullable_baserels是由jointree中的某些外连接中值可为空的baseRelids集合;*这些是在WHERE子句、SELECTtargetlist等下面可能为空的树。*这是在deconstruct_jointree中处理获得的。*///Nullable-side端的"baserels"Relidsnullable_baserels;/**join_rel_listisalistofalljoin-relationRelOptInfoswehave*consideredinthisplanningrun.Forsmallproblemswejustscanthe*listtodolookups,butwhentherearemanyjoinrelationswebuilda*hashtableforfasterlookups.Thehashtableispresentandvalid*whenjoin_rel_hashisnotNULL.Notethatwestillmaintainthelist*evenwhenusingthehashtableforlookups;thissimplifieslifefor*GEQO.*join_rel_list是在计划执行中考虑的所有连接关系RelOptInfos的链表。*对于小问题,只需要扫描链表执行查找,但是当存在许多连接关系时,*需要构建一个散列表来进行更快的查找。*当join_rel_hash不为空时,哈希表是有效可用于查询的。*注意,即使在使用哈希表进行查找时,仍然维护该链表;这简化了GEQO(遗传算法)的生命周期。*///参与连接的Relation的RelOptInfo链表List*join_rel_list;/*listofjoin-relationRelOptInfos*///可加快链表访问的hash表structHTAB*join_rel_hash;/*optionalhashtableforjoinrelations*//**Whendoingadynamic-programming-stylejoinsearch,join_rel_level[k]*isalistofalljoin-relationRelOptInfosoflevelk,and*join_cur_levelisthecurrentlevel.Newjoin-relationRelOptInfosare*automaticallyaddedtothejoin_rel_level[join_cur_level]list.*join_rel_levelisNULLifnotinuse.*在执行动态规划算法的连接搜索时,join_rel_level[k]是k级的所有连接关系RelOptInfos的列表,*join_cur_level是当前级别。*新的连接关系RelOptInfos会自动添加到join_rel_level[join_cur_level]链表中。*如果不使用join_rel_level,则为NULL。*///RelOptInfo指针链表数组,k层的join存储在[k]中List**join_rel_level;/*listsofjoin-relationRelOptInfos*///当前的join层次intjoin_cur_level;/*indexoflistbeingextended*///查询的初始化计划链表List*init_plans;/*initSubPlansforquery*///CTE子计划ID链表List*cte_plan_ids;/*per-CTE-itemlistofsubplanIDs*///MULTIEXPR子查询输出的参数链表的链表List*multiexpr_params;/*ListofListsofParamsforMULTIEXPR*subqueryoutputs*///活动的等价类链表List*eq_classes;/*listofactiveEquivalenceClasses*///规范化的PathKey链表List*canon_pathkeys;/*listof"canonical"PathKeys*///外连接约束条件链表(左)List*left_join_clauses;/*listofRestrictInfosformergejoinable*outerjoinclausesw/nonnullablevaron*left*///外连接约束条件链表(右)List*right_join_clauses;/*listofRestrictInfosformergejoinable*outerjoinclausesw/nonnullablevaron*right*///全连接约束条件链表List*full_join_clauses;/*listofRestrictInfosformergejoinable*fulljoinclauses*///特殊连接信息链表List*join_info_list;/*listofSpecialJoinInfos*///AppendRelInfo链表List*append_rel_list;/*listofAppendRelInfos*///PlanRowMarks链表List*rowMarks;/*listofPlanRowMarks*///PHI链表List*placeholder_list;/*listofPlaceHolderInfos*///外键信息链表List*fkey_list;/*listofForeignKeyOptInfos*///query_planner()要求的PathKeys链表List*query_pathkeys;/*desiredpathkeysforquery_planner()*///分组子句路径键List*group_pathkeys;/*groupClausepathkeys,ifany*///窗口函数路径键List*window_pathkeys;/*pathkeysofbottomwindow,ifany*///distinctClause路径键List*distinct_pathkeys;/*distinctClausepathkeys,ifany*///排序路径键List*sort_pathkeys;/*sortClausepathkeys,ifany*///已规范化的分区SchemaList*part_schemes;/*Canonicalisedpartitionschemesusedinthe*query.*///尝试连接的RelOptInfo链表List*initial_rels;/*RelOptInfoswearenowtryingtojoin*//*Usefetch_upper_rel()togetanyparticularupperrel*///上层的RelOptInfo链表List*upper_rels[UPPERREL_FINAL+1];/*upper-relRelOptInfos*//*Resulttlistschosenbygrouping_plannerforupper-stageprocessing*///grouping_planner为上层处理选择的结果tlistsstructPathTarget*upper_targets[UPPERREL_FINAL+1];///**grouping_plannerpassesbackitsfinalprocessedtargetlisthere,for*useinrelabelingthetopmosttlistofthefinishedPlan.*grouping_planner在这里传回它最终处理过的targetlist,用于重新标记已完成计划的最顶层tlist。*/////最后需处理的投影列List*processed_tlist;/*Fieldsfilledduringcreate_plan()foruseinsetrefs.c*///setrefs.c中在create_plan()函数调用期间填充的字段//分组函数属性映射AttrNumber*grouping_map;/*forGroupingFuncfixup*///MinMaxAggInfos链表List*minmax_aggs;/*ListofMinMaxAggInfos*///内存上下文MemoryContextplanner_cxt;/*contextholdingPlannerInfo*///关系的page计数doubletotal_table_pages;/*#ofpagesinalltablesofquery*///query_planner输入参数:元组处理比例doubletuple_fraction;/*tuple_fractionpassedtoquery_planner*///query_planner输入参数:limit_tupledoublelimit_tuples;/*limit_tuplespassedtoquery_planner*///表达式的最小安全等级Indexqual_security_level;/*minimumsecurity_levelforquals*//*Note:qual_security_leveliszeroiftherearenosecurityQuals*///注意:如果没有securityQuals,则qual_security_level是NULL(0)//如目标relation是分区表的child/partition/分区表,则通过此字段标记InheritanceKindinhTargetKind;/*indicatesifthetargetrelationisan*inheritancechildorpartitionora*partitionedtable*///是否存在RTE_JOIN的RTEboolhasJoinRTEs;/*trueifanyRTEsareRTE_JOINkind*///是否存在标记为LATERAL的RTEboolhasLateralRTEs;/*trueifanyRTEsaremarkedLATERAL*///是否存在已在jointree删除的RTEboolhasDeletedRTEs;/*trueifanyRTEwasdeletedfromjointree*///是否存在Having子句boolhasHavingQual;/*trueifhavingQualwasnon-null*///如约束条件中存在pseudoconstant=true,则此字段为TboolhasPseudoConstantQuals;/*trueifanyRestrictInfohas*pseudoconstant=true*///是否存在递归语句boolhasRecursion;/*trueifplanningarecursiveWITHitem*//*ThesefieldsareusedonlywhenhasRecursionistrue:*///这些字段仅在hasRecursion为T时使用://工作表的PARAM_EXECIDintwt_param_id;/*PARAM_EXECIDfortheworktable*///非递归模式的访问路径structPath*non_recursive_path;/*apathfornon-recursiveterm*//*Thesefieldsareworkspaceforcreateplan.c*///这些字段用于createplan.c//当前节点之上的外部relsRelidscurOuterRels;/*outerrelsabovecurrentnode*///未赋值的NestLoopParams参数List*curOuterParams;/*not-yet-assignedNestLoopParams*//*optionalprivatedataforjoin_search_hook,e.g.,GEQO*///可选的join_search_hook私有数据,例如GEQOvoid*join_search_private;/*Doesthisquerymodifyanypartitionkeycolumns?*///该查询是否更新分区键列?boolpartColsUpdated;}PlannerInfo;
“PostgreSQL中分区表查询相关的重要数据结构有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。