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