溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函數(shù)有什么作用

發(fā)布時間:2021-11-10 15:53:37 來源:億速云 閱讀:210 作者:iii 欄目:關(guān)系型數(shù)據(jù)庫

這篇文章主要介紹“PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函數(shù)有什么作用”,在日常操作中,相信很多人在PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函數(shù)有什么作用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函數(shù)有什么作用”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

fetch_upper_rel函數(shù)構(gòu)建用以表示查詢優(yōu)化器生成的最終關(guān)系(用RelOptInfo數(shù)據(jù)結(jié)構(gòu)表示),get_cheapest_fractional_path函數(shù)根據(jù)輸入的RelOptInfo數(shù)據(jù)結(jié)構(gòu)找到成本最低的訪問路徑。

一、源碼解讀

fetch_upper_rel
從優(yōu)化器信息中的upper_rels數(shù)據(jù)中獲取用以表示查詢優(yōu)化器生成的最終關(guān)系.

//--------------------------------------------------------------------------- fetch_upper_rel

/*
 * fetch_upper_rel
 *      Build a RelOptInfo describing some post-scan/join query processing,
 *      or return a pre-existing one if somebody already built it.
 *      構(gòu)建RelOptInfo數(shù)據(jù)結(jié)構(gòu),用以表示post-scan/join查詢過程.如已存在,則直接返回.
 *
 * An "upper" relation is identified by an UpperRelationKind and a Relids set.
 * The meaning of the Relids set is not specified here, and very likely will
 * vary for different relation kinds.
 * 一個“上級”關(guān)系是由一個UpperRelationKind和一個Relids集合來標識。
 * 在這里沒有指定Relids集合的含義,并且很可能會因不同的關(guān)系類型而不同。
 *
 * Most of the fields in an upper-level RelOptInfo are not used and are not
 * set here (though makeNode should ensure they're zeroes).  We basically only
 * care about fields that are of interest to add_path() and set_cheapest().
 * 上層RelOptInfo中的大多數(shù)字段都沒有使用,也沒有在這里設(shè)置(盡管makeNode應(yīng)該確保它們是NULL)。
 * 基本上只關(guān)心add_path()和set_cheap()函數(shù)所感興趣的字段。
 */
RelOptInfo *
fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)
{
    RelOptInfo *upperrel;
    ListCell   *lc;

    /*
     * For the moment, our indexing data structure is just a List for each
     * relation kind.  If we ever get so many of one kind that this stops
     * working well, we can improve it.  No code outside this function should
     * assume anything about how to find a particular upperrel.
     * 目前,我們已索引的數(shù)據(jù)結(jié)構(gòu)只是每個關(guān)系類型的鏈表。
     * 這個函數(shù)之外的任何代碼都不應(yīng)該假定如何找到一個特定的上層關(guān)系。
     */

    /* If we already made this upperrel for the query, return it */
    //如果已經(jīng)構(gòu)造了該查詢的上層關(guān)系,直接返回
    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);

    /* cheap startup cost is interesting iff not all tuples to be retrieved */
    //低廉的啟動成本在較少的元組返回的情況是比較讓人關(guān)心的.
    upperrel->consider_startup = (root->tuple_fraction > 0);//如非全部返回元組,則需要考慮啟動成本
    upperrel->consider_param_startup = false;
    upperrel->consider_parallel = false;    /* 以后可能會有變化;might get changed later */
    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

/*
 * get_cheapest_fractional_path
 *    Find the cheapest path for retrieving a specified fraction of all
 *    the tuples expected to be returned by the given relation.
 *    給定關(guān)系,找到成本最低的訪問路徑,該路徑返回返回預(yù)期設(shè)定元組數(shù)。
 * 
 * We interpret tuple_fraction the same way as grouping_planner.
 * 我們用grouping_planner函數(shù)來獲取tuple_fraction。
 *
 * We assume set_cheapest() has been run on the given rel.
 * 假定set_cheapest()函數(shù)已在給定的關(guān)系上執(zhí)行.
 */
Path *
get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)
{
    Path       *best_path = rel->cheapest_total_path;
    ListCell   *l;

    /* If all tuples will be retrieved, just return the cheapest-total path */
    //如果需要檢索所有元組,則返回總成本最低的訪問路徑
    if (tuple_fraction <= 0.0)
        return best_path;

    /* Convert absolute # of tuples to a fraction; no need to clamp to 0..1 */
    //根據(jù)比例給出需返回行數(shù)
    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

 /*
  * compare_path_fractional_costs
  *    Return -1, 0, or +1 according as path2 is cheaper, the same cost,
  *    or more expensive than path3 for fetching the specified fraction
  *    of the total tuples.
  *    返回值:
  *    -1:相對于path3,path2成本更低;
  *     0:與path3成本相同
  *     1:比path3成本更高
  *
  * If fraction is <= 0 or > 1, we interpret it as 1, ie, we select the
  * path with the cheaper total_cost.
  * 如果fraction≤0或者大于1,則選擇總成本最低的訪問路徑
  */
 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
 /*
  * compare_path_costs
  *    Return -1, 0, or +1 according as path2 is cheaper, the same cost,
  *    or more expensive than path3 for the specified criterion.
  * 給定標準,返回比較結(jié)果.
  * 返回值:
  *    -1:相對于path3,path2成本更低;
  *     0:與path3成本相同
  *     1:比path3成本更高
  */
 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 paths have the same startup cost (not at all unlikely), order
          * them by total cost.
          */
         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 paths have the same total cost, order them by startup cost.
          */
         if (path2->startup_cost < path3->startup_cost)
             return -1;
         if (path2->startup_cost > path3->startup_cost)
             return +1;
     }
     return 0;
 }

到此,關(guān)于“PostgreSQL中fetch_upper_rel和get_cheapest_fractional_path函數(shù)有什么作用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI