Thread: Shouldn't cost_append() also scale the partial path's cost?
Like in cost_seqscan(), I'd expect the subpath cost to be divided among parallel workers. The patch below shows what I mean. Am I right? -- Antonin Houska Web: https://www.cybertec-postgresql.com diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index ef475d95a1..5427822e0e 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -2313,19 +2313,29 @@ cost_append(AppendPath *apath) * Apply parallel divisor to subpaths. Scale the number of rows * for each partial subpath based on the ratio of the parallel * divisor originally used for the subpath to the one we adopted. - * Also add the cost of partial paths to the total cost, but - * ignore non-partial paths for now. + * Also add the scaled cost of partial paths to the total cost, + * but ignore non-partial paths for now. */ if (i < apath->first_partial_path) apath->path.rows += subpath->rows / parallel_divisor; else { double subpath_parallel_divisor; + double scale_factor; + Cost run_cost; subpath_parallel_divisor = get_parallel_divisor(subpath); - apath->path.rows += subpath->rows * (subpath_parallel_divisor / - parallel_divisor); - apath->path.total_cost += subpath->total_cost; + scale_factor = subpath_parallel_divisor / parallel_divisor; + apath->path.rows += subpath->rows * scale_factor; + /* + * XXX run_cost includes both CPU cost, which is divided among + * workers, and disk cost, which is not. Unfortunately we + * don't have enough information to separate the two, so scale + * the whole run_cost. + */ + run_cost = subpath->total_cost - subpath->startup_cost; + apath->path.total_cost += subpath->startup_cost + + run_cost * scale_factor;; } apath->path.rows = clamp_row_est(apath->path.rows);
At Wed, 14 Jun 2023 14:36:54 +0200, Antonin Houska <ah@cybertec.at> wrote in > Like in cost_seqscan(), I'd expect the subpath cost to be divided among > parallel workers. The patch below shows what I mean. Am I right? If I've got it right, the total cost of a partial seqscan path comprises a distributed CPU run cost and an undistributed disk run cost. If we want to adjust for a different worker number, we should only tweak the CPU component of the total cost. By default, if one page contains 100 rows (I guess a moderate ratio), these two costs are balanced at a 1:1 ratio and the CPU run cost and disk run cost in a partial seqscan path is 1:n (n = #workers). If we adjust the run cost in the porposed manner, it adjusts the CPU run cost correctly but in turn the disk run cost gets wrong (by a larger error in this premise). In short, it will get wrong in a different way. Actually it looks strange that rows are adjusted but cost is not, so we might want to add an explanation in this aspect. regards. -- Kyotaro Horiguchi NTT Open Source Software Center