这篇文章主要介绍“PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函数有什么作用”,在日常操作中,相信很多人在PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函数有什么作用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函数有什么作用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

fetch_upper_rel函数构建用以表示查询优化器生成的最终关系(用RelOptInfo数据结构表示),get_cheapest_fractional_path函数根据输入的RelOptInfo数据结构找到成本最低的访问路径。

一、源码解读

fetch_upper_rel
从优化器信息中的upper_rels数据中获取用以表示查询优化器生成的最终关系.

//---------------------------------------------------------------------------fetch_upper_rel/**fetch_upper_rel*BuildaRelOptInfodescribingsomepost-scan/joinqueryprocessing,*orreturnapre-existingoneifsomebodyalreadybuiltit.*构建RelOptInfo数据结构,用以表示post-scan/join查询过程.如已存在,则直接返回.**An"upper"relationisidentifiedbyanUpperRelationKindandaRelidsset.*ThemeaningoftheRelidssetisnotspecifiedhere,andverylikelywill*varyfordifferentrelationkinds.*一个“上级”关系是由一个UpperRelationKind和一个Relids集合来标识。*在这里没有指定Relids集合的含义,并且很可能会因不同的关系类型而不同。**Mostofthefieldsinanupper-levelRelOptInfoarenotusedandarenot*sethere(thoughmakeNodeshouldensurethey'rezeroes).Webasicallyonly*careaboutfieldsthatareofinteresttoadd_path()andset_cheapest().*上层RelOptInfo中的大多数字段都没有使用,也没有在这里设置(尽管makeNode应该确保它们是NULL)。*基本上只关心add_path()和set_cheap()函数所感兴趣的字段。*/RelOptInfo*fetch_upper_rel(PlannerInfo*root,UpperRelationKindkind,Relidsrelids){RelOptInfo*upperrel;ListCell*lc;/**Forthemoment,ourindexingdatastructureisjustaListforeach*relationkind.Ifweevergetsomanyofonekindthatthisstops*workingwell,wecanimproveit.Nocodeoutsidethisfunctionshould*assumeanythingabouthowtofindaparticularupperrel.*目前,我们已索引的数据结构只是每个关系类型的链表。*这个函数之外的任何代码都不应该假定如何找到一个特定的上层关系。*//*Ifwealreadymadethisupperrelforthequery,returnit*///如果已经构造了该查询的上层关系,直接返回foreach(lc,root->upper_rels[kind]){upperrel=(RelOptInfo*)lfirst(lc);if(bms_equal(upperrel->relids,relids))returnupperrel;}upperrel=makeNode(RelOptInfo);upperrel->reloptkind=RELOPT_UPPER_REL;upperrel->relids=bms_copy(relids);/*cheapstartupcostisinterestingiffnotalltuplestoberetrieved*///低廉的启动成本在较少的元组返回的情况是比较让人关心的.upperrel->consider_startup=(root->tuple_fraction>0);//如非全部返回元组,则需要考虑启动成本upperrel->consider_param_startup=false;upperrel->consider_parallel=false;/*以后可能会有变化;mightgetchangedlater*/upperrel->reltarget=create_empty_pathtarget();upperrel->pathlist=NIL;upperrel->cheapest_startup_path=NULL;upperrel->cheapest_total_path=NULL;upperrel->cheapest_unique_path=NULL;upperrel->cheapest_parameterized_paths=NIL;root->upper_rels[kind]=lappend(root->upper_rels[kind],upperrel);returnupperrel;}

get_cheapest_fractional_path
get_cheapest_fractional_path通过对RelOptInfo中的访问路径两两比较,获取成本最低的访问路径.

//---------------------------------------------------------------------------get_cheapest_fractional_path/**get_cheapest_fractional_path*Findthecheapestpathforretrievingaspecifiedfractionofall*thetuplesexpectedtobereturnedbythegivenrelation.*给定关系,找到成本最低的访问路径,该路径返回返回预期设定元组数。**Weinterprettuple_fractionthesamewayasgrouping_planner.*我们用grouping_planner函数来获取tuple_fraction。**Weassumeset_cheapest()hasbeenrunonthegivenrel.*假定set_cheapest()函数已在给定的关系上执行.*/Path*get_cheapest_fractional_path(RelOptInfo*rel,doubletuple_fraction){Path*best_path=rel->cheapest_total_path;ListCell*l;/*Ifalltupleswillberetrieved,justreturnthecheapest-totalpath*///如果需要检索所有元组,则返回总成本最低的访问路径if(tuple_fraction<=0.0)returnbest_path;/*Convertabsolute#oftuplestoafraction;noneedtoclampto0..1*///根据比例给出需返回行数if(tuple_fraction>=1.0&&best_path->rows>0)tuple_fraction/=best_path->rows;foreach(l,rel->pathlist){Path*path=(Path*)lfirst(l);//best_path的成本比path要低或相同,保留if(path==rel->cheapest_total_path||compare_fractional_path_costs(best_path,path,tuple_fraction)<=0)continue;//否则,选择新的访问路径best_path=path;}returnbest_path;}//------------------------------------------------------compare_path_costs/**compare_path_fractional_costs*Return-1,0,or+1accordingaspath2ischeaper,thesamecost,*ormoreexpensivethanpath3forfetchingthespecifiedfraction*ofthetotaltuples.*返回值:*-1:相对于path3,path2成本更低;*0:与path3成本相同*1:比path3成本更高**Iffractionis<=0or>1,weinterpretitas1,ie,weselectthe*pathwiththecheapertotal_cost.*如果fraction≤0或者大于1,则选择总成本最低的访问路径*/intcompare_fractional_path_costs(Path*path2,Path*path3,doublefraction){Costcost1,cost2;if(fraction<=0.0||fraction>=1.0)returncompare_path_costs(path2,path3,TOTAL_COST);cost1=path2->startup_cost+fraction*(path2->total_cost-path2->startup_cost);cost2=path3->startup_cost+fraction*(path3->total_cost-path3->startup_cost);if(cost1<cost2)return-1;if(cost1>cost2)return+1;return0;}//---------------------------------------compare_path_costs/**compare_path_costs*Return-1,0,or+1accordingaspath2ischeaper,thesamecost,*ormoreexpensivethanpath3forthespecifiedcriterion.*给定标准,返回比较结果.*返回值:*-1:相对于path3,path2成本更低;*0:与path3成本相同*1:比path3成本更高*/intcompare_path_costs(Path*path2,Path*path3,CostSelectorcriterion){if(criterion==STARTUP_COST)//启动成本{if(path2->startup_cost<path3->startup_cost)return-1;if(path2->startup_cost>path3->startup_cost)return+1;/**Ifpathshavethesamestartupcost(notatallunlikely),order*thembytotalcost.*/if(path2->total_cost<path3->total_cost)return-1;if(path2->total_cost>path3->total_cost)return+1;}else//总成本{if(path2->total_cost<path3->total_cost)return-1;if(path2->total_cost>path3->total_cost)return+1;/**Ifpathshavethesametotalcost,orderthembystartupcost.*/if(path2->startup_cost<path3->startup_cost)return-1;if(path2->startup_cost>path3->startup_cost)return+1;}return0;}

到此,关于“PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函数有什么作用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!