这篇文章主要介绍“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
RelOptInfo *
fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
{
RelOptInfo *upperrel;
ListCell *lc;
//如果已经构造了该查询的上层关系,直接返回
foreach(lc, root->upper_rels[kind])
{
upperrel = (RelOptInfo *) lfirst(lc);
if (bms_equal(upperrel->relids, relids))
return upperrel;
}
upperrel = makeNode(RelOptInfo);
upperrel->reloptkind = RELOPT_UPPER_REL;
upperrel->relids = bms_copy(relids);
//低廉的启动成本在较少的元组返回的情况是比较让人关心的.
upperrel->consider_startup = (root->tuple_fraction > 0);//如非全部返回元组,则需要考虑启动成本
upperrel->consider_param_startup = false;
upperrel->consider_parallel = false;
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);
return upperrel;
}
get_cheapest_fractional_path
get_cheapest_fractional_path通过对RelOptInfo中的访问路径两两比较,获取成本最低的访问路径.
//--------------------------------------------------------------------------- get_cheapest_fractional_path
Path *
get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)
{
Path *best_path = rel->cheapest_total_path;
ListCell *l;
//如果需要检索所有元组,则返回总成本最低的访问路径
if (tuple_fraction <= 0.0)
return best_path;
//根据比例给出需返回行数
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;
}
return best_path;
}
//------------------------------------------------------ compare_path_costs
int
compare_fractional_path_costs(Path *path2, Path *path3,
double fraction)
{
Cost cost1,
cost2;
if (fraction <= 0.0 || fraction >= 1.0)
return compare_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;
return 0;
}
//--------------------------------------- compare_path_costs
int
compare_path_costs(Path *path2, Path *path3, CostSelector criterion)
{
if (criterion == STARTUP_COST)//启动成本
{
if (path2->startup_cost < path3->startup_cost)
return -1;
if (path2->startup_cost > path3->startup_cost)
return +1;
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;
if (path2->startup_cost < path3->startup_cost)
return -1;
if (path2->startup_cost > path3->startup_cost)
return +1;
}
return 0;
}
到此,关于“PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函数有什么作用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!