PostgreSQL在何处处理 sql查询之五十六

接前面,继续分析 :

    cheapest_startup_path = cheapest_total_path = NULL;
    have_parameterized_paths = false;

    foreach(p, parent_rel->pathlist)
    {
        Path       *path = (Path *) lfirst(p);
        int            cmp;

        /* We only consider unparameterized paths in this step */
        if (path->param_info)
        {
            have_parameterized_paths = true;
            continue;
        }

        if (cheapest_total_path == NULL)
        {
            cheapest_startup_path = cheapest_total_path = path;

            fprintf(stderr,"Here cheapest_total_path is set\n");

            continue;
        }

                
        /*
         * If we find two paths of identical costs, try to keep the
         * better-sorted one.  The paths might have unrelated sort orderings,
         * in which case we can only guess which might be better to keep, but
         * if one is superior then we definitely should keep that one.
         */
        cmp = compare_path_costs(cheapest_startup_path, path, STARTUP_COST);


        if (cmp > 0 ||
            (cmp == 0 &&
             compare_pathkeys(cheapest_startup_path->pathkeys,
                              path->pathkeys) == PATHKEYS_BETTER2))
            cheapest_startup_path = path;

        cmp = compare_path_costs(cheapest_total_path, path, TOTAL_COST);


        if (cmp > 0 ||
            (cmp == 0 &&
             compare_pathkeys(cheapest_total_path->pathkeys,
                              path->pathkeys) == PATHKEYS_BETTER2))
            cheapest_total_path = path;

    }

由于我执行的是简单查询,所以  parent_rel->pathlist 的长度是1,故此:

上面的for 循环可以简化为:

    cheapest_startup_path = cheapest_total_path = NULL;
    have_parameterized_paths = false;

    foreach(p, parent_rel->pathlist)
    {
        Path       *path = (Path *) lfirst(p);
        int            cmp;

        /* We only consider unparameterized paths in this step */
        if (path->param_info)
        {
            have_parameterized_paths = true;
            continue;
        }

        if (cheapest_total_path == NULL)
        {
            cheapest_startup_path = cheapest_total_path = path;
continue;
        }
                ...
        }
...
}

因为只有一个path,所以这个就是最cheapest 的了。后面一小段代码就无视了:

    if (cheapest_total_path == NULL)
        elog(ERROR, "could not devise a query plan for the given query");

    parent_rel->cheapest_startup_path = cheapest_startup_path;
    parent_rel->cheapest_total_path = cheapest_total_path;
    parent_rel->cheapest_unique_path = NULL;    /* computed only if needed */

    /* Seed the parameterized-paths list with the cheapest total */
    parent_rel->cheapest_parameterized_paths = list_make1(cheapest_total_path);

    /* And, if there are any parameterized paths, add them in one at a time */
    if (have_parameterized_paths)
    {
        foreach(p, parent_rel->pathlist)
        {
            Path       *path = (Path *) lfirst(p);

            if (path->param_info)
                add_parameterized_path(parent_rel, path);
        }
    }

 可以说,还应当向上回溯,找到真正何处开始真正设置path。

cheapest_startup_path = cheapest_total_path = path; 
也就是说,要查
->pathlist

原文地址:https://www.cnblogs.com/gaojian/p/3123568.html