mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-05 19:09:58 +08:00
postgres_fdw: Fix cost estimation for aggregate pushdown.
In commit 7012b132d0
, which added support for aggregate pushdown in
postgres_fdw, the expense of evaluating the final scan/join target
computed by make_group_input_target() was not accounted for at all in
costing aggregate pushdown paths with local statistics. The right fix
for this would be to have a separate upper stage to adjust the final
scan/join relation (see comments for apply_scanjoin_target_to_paths());
but for now, fix by adding the tlist eval cost when costing aggregate
pushdown paths with local statistics.
Apply this to HEAD only to avoid destabilizing existing plan choices.
Author: Etsuro Fujita
Reviewed-By: Antonin Houska
Discussion: https://postgr.es/m/5C66A056.60007%40lab.ntt.co.jp
This commit is contained in:
parent
47a338cfcd
commit
edbcbe277d
@ -2842,12 +2842,18 @@ estimate_path_cost_size(PlannerInfo *root,
|
||||
}
|
||||
else if (IS_UPPER_REL(foreignrel))
|
||||
{
|
||||
RelOptInfo *outerrel = fpinfo->outerrel;
|
||||
PgFdwRelationInfo *ofpinfo;
|
||||
AggClauseCosts aggcosts;
|
||||
double input_rows;
|
||||
int numGroupCols;
|
||||
double numGroups = 1;
|
||||
|
||||
/* The upper relation should have its outer relation set */
|
||||
Assert(outerrel);
|
||||
/* and that outer relation should have its reltarget set */
|
||||
Assert(outerrel->reltarget);
|
||||
|
||||
/*
|
||||
* This cost model is mixture of costing done for sorted and
|
||||
* hashed aggregates in cost_agg(). We are not sure which
|
||||
@ -2856,7 +2862,7 @@ estimate_path_cost_size(PlannerInfo *root,
|
||||
* and all finalization and run cost are added in total_cost.
|
||||
*/
|
||||
|
||||
ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private;
|
||||
ofpinfo = (PgFdwRelationInfo *) outerrel->fdw_private;
|
||||
|
||||
/* Get rows and width from input rel */
|
||||
input_rows = ofpinfo->rows;
|
||||
@ -2909,11 +2915,13 @@ estimate_path_cost_size(PlannerInfo *root,
|
||||
|
||||
/*-----
|
||||
* Startup cost includes:
|
||||
* 1. Startup cost for underneath input relation
|
||||
* 1. Startup cost for underneath input relation, adjusted for
|
||||
* tlist replacement by apply_scanjoin_target_to_paths()
|
||||
* 2. Cost of performing aggregation, per cost_agg()
|
||||
*-----
|
||||
*/
|
||||
startup_cost = ofpinfo->rel_startup_cost;
|
||||
startup_cost += outerrel->reltarget->cost.startup;
|
||||
startup_cost += aggcosts.transCost.startup;
|
||||
startup_cost += aggcosts.transCost.per_tuple * input_rows;
|
||||
startup_cost += aggcosts.finalCost.startup;
|
||||
@ -2921,11 +2929,13 @@ estimate_path_cost_size(PlannerInfo *root,
|
||||
|
||||
/*-----
|
||||
* Run time cost includes:
|
||||
* 1. Run time cost of underneath input relation
|
||||
* 1. Run time cost of underneath input relation, adjusted for
|
||||
* tlist replacement by apply_scanjoin_target_to_paths()
|
||||
* 2. Run time cost of performing aggregation, per cost_agg()
|
||||
*-----
|
||||
*/
|
||||
run_cost = ofpinfo->rel_total_cost - ofpinfo->rel_startup_cost;
|
||||
run_cost += outerrel->reltarget->cost.per_tuple * input_rows;
|
||||
run_cost += aggcosts.finalCost.per_tuple * numGroups;
|
||||
run_cost += cpu_tuple_cost * numGroups;
|
||||
|
||||
|
@ -7113,6 +7113,10 @@ apply_scanjoin_target_to_paths(PlannerInfo *root,
|
||||
* confused in createplan.c if they don't agree. We must do this now so
|
||||
* that any append paths made in the next part will use the correct
|
||||
* pathtarget (cf. create_append_path).
|
||||
*
|
||||
* Note that this is also necessary if GetForeignUpperPaths() gets called
|
||||
* on the final scan/join relation or on any of its children, since the
|
||||
* FDW might look at the rel's target to create ForeignPaths.
|
||||
*/
|
||||
rel->reltarget = llast_node(PathTarget, scanjoin_targets);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user