1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-05 23:56:58 +03:00

Increase DEFAULT_FDW_TUPLE_COST from 0.01 to 0.2

0.01 was unrealistically low as it's the same as the default
cpu_tuple_cost and 10x cheaper than the default parallel_tuple_cost.
It's hard to imagine a situation where fetching a tuple from a foreign
server would be cheaper than fetching one from a parallel worker.

After some experimentation on a loopback server, somewhere between 0.15
and 0.3 seems more realistic.  Here we split the difference and set it
to 0.2.

This will cause operations that reduce the number of tuples (e.g.
aggregation) to be more likely to take place on the foreign server.

Adjusting this causes some plan changes in the postgres_fdw regression
tests.  This is because penalizing each Path with the additional tuple
costs causes some dilution of the costs of the other operations being
charged for and results in various paths appearing to be closer to the
same costs such that add_path's STD_FUZZ_FACTOR is more likely to see two
paths as costing (fuzzily) the same.  This isn't ideal, but it shouldn't
be reason enough to use artificially low costs.

Discussion: https://postgr.es/m/CAApHDvopVjjfh5c1Ed2HRvDdfom2dEpMwwiu5-f1AnmYprJngA@mail.gmail.com
This commit is contained in:
David Rowley 2023-11-02 14:30:15 +13:00
parent 4210b55f59
commit cac169d686
2 changed files with 62 additions and 69 deletions

View File

@ -9729,21 +9729,19 @@ SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE
-- test FOR UPDATE; partitionwise join does not apply -- test FOR UPDATE; partitionwise join does not apply
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1;
QUERY PLAN QUERY PLAN
-------------------------------------------------------------- --------------------------------------------------------
LockRows LockRows
-> Sort -> Nested Loop
Sort Key: t1.a Join Filter: (t1.a = t2.b)
-> Hash Join -> Append
Hash Cond: (t2.b = t1.a) -> Foreign Scan on ftprt1_p1 t1_1
-> Foreign Scan on ftprt1_p2 t1_2
-> Materialize
-> Append -> Append
-> Foreign Scan on ftprt2_p1 t2_1 -> Foreign Scan on ftprt2_p1 t2_1
-> Foreign Scan on ftprt2_p2 t2_2 -> Foreign Scan on ftprt2_p2 t2_2
-> Hash (10 rows)
-> Append
-> Foreign Scan on ftprt1_p1 t1_1
-> Foreign Scan on ftprt1_p2 t1_2
(12 rows)
SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1;
a | b a | b
@ -9778,18 +9776,16 @@ ANALYZE fpagg_tab_p3;
SET enable_partitionwise_aggregate TO false; SET enable_partitionwise_aggregate TO false;
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
QUERY PLAN QUERY PLAN
----------------------------------------------------------- -----------------------------------------------------
Sort GroupAggregate
Sort Key: pagg_tab.a Group Key: pagg_tab.a
-> HashAggregate Filter: (avg(pagg_tab.b) < '22'::numeric)
Group Key: pagg_tab.a -> Append
Filter: (avg(pagg_tab.b) < '22'::numeric) -> Foreign Scan on fpagg_tab_p1 pagg_tab_1
-> Append -> Foreign Scan on fpagg_tab_p2 pagg_tab_2
-> Foreign Scan on fpagg_tab_p1 pagg_tab_1 -> Foreign Scan on fpagg_tab_p3 pagg_tab_3
-> Foreign Scan on fpagg_tab_p2 pagg_tab_2 (7 rows)
-> Foreign Scan on fpagg_tab_p3 pagg_tab_3
(9 rows)
-- Plan with partitionwise aggregates is enabled -- Plan with partitionwise aggregates is enabled
SET enable_partitionwise_aggregate TO true; SET enable_partitionwise_aggregate TO true;
@ -9823,34 +9819,32 @@ SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 O
-- Should have all the columns in the target list for the given relation -- Should have all the columns in the target list for the given relation
EXPLAIN (VERBOSE, COSTS OFF) EXPLAIN (VERBOSE, COSTS OFF)
SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
QUERY PLAN QUERY PLAN
------------------------------------------------------------------------ --------------------------------------------------------------------------------------------
Sort Merge Append
Output: t1.a, (count(((t1.*)::pagg_tab)))
Sort Key: t1.a Sort Key: t1.a
-> Append -> GroupAggregate
-> HashAggregate Output: t1.a, count(((t1.*)::pagg_tab))
Output: t1.a, count(((t1.*)::pagg_tab)) Group Key: t1.a
Group Key: t1.a Filter: (avg(t1.b) < '22'::numeric)
Filter: (avg(t1.b) < '22'::numeric) -> Foreign Scan on public.fpagg_tab_p1 t1
-> Foreign Scan on public.fpagg_tab_p1 t1 Output: t1.a, t1.*, t1.b
Output: t1.a, t1.*, t1.b Remote SQL: SELECT a, b, c FROM public.pagg_tab_p1 ORDER BY a ASC NULLS LAST
Remote SQL: SELECT a, b, c FROM public.pagg_tab_p1 -> GroupAggregate
-> HashAggregate Output: t1_1.a, count(((t1_1.*)::pagg_tab))
Output: t1_1.a, count(((t1_1.*)::pagg_tab)) Group Key: t1_1.a
Group Key: t1_1.a Filter: (avg(t1_1.b) < '22'::numeric)
Filter: (avg(t1_1.b) < '22'::numeric) -> Foreign Scan on public.fpagg_tab_p2 t1_1
-> Foreign Scan on public.fpagg_tab_p2 t1_1 Output: t1_1.a, t1_1.*, t1_1.b
Output: t1_1.a, t1_1.*, t1_1.b Remote SQL: SELECT a, b, c FROM public.pagg_tab_p2 ORDER BY a ASC NULLS LAST
Remote SQL: SELECT a, b, c FROM public.pagg_tab_p2 -> GroupAggregate
-> HashAggregate Output: t1_2.a, count(((t1_2.*)::pagg_tab))
Output: t1_2.a, count(((t1_2.*)::pagg_tab)) Group Key: t1_2.a
Group Key: t1_2.a Filter: (avg(t1_2.b) < '22'::numeric)
Filter: (avg(t1_2.b) < '22'::numeric) -> Foreign Scan on public.fpagg_tab_p3 t1_2
-> Foreign Scan on public.fpagg_tab_p3 t1_2 Output: t1_2.a, t1_2.*, t1_2.b
Output: t1_2.a, t1_2.*, t1_2.b Remote SQL: SELECT a, b, c FROM public.pagg_tab_p3 ORDER BY a ASC NULLS LAST
Remote SQL: SELECT a, b, c FROM public.pagg_tab_p3 (23 rows)
(25 rows)
SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
a | count a | count
@ -9866,24 +9860,23 @@ SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1;
-- When GROUP BY clause does not match with PARTITION KEY. -- When GROUP BY clause does not match with PARTITION KEY.
EXPLAIN (COSTS OFF) EXPLAIN (COSTS OFF)
SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1; SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1;
QUERY PLAN QUERY PLAN
----------------------------------------------------------------- -----------------------------------------------------------
Sort Finalize GroupAggregate
Sort Key: pagg_tab.b Group Key: pagg_tab.b
-> Finalize HashAggregate Filter: (sum(pagg_tab.a) < 700)
Group Key: pagg_tab.b -> Merge Append
Filter: (sum(pagg_tab.a) < 700) Sort Key: pagg_tab.b
-> Append -> Partial GroupAggregate
-> Partial HashAggregate Group Key: pagg_tab.b
Group Key: pagg_tab.b -> Foreign Scan on fpagg_tab_p1 pagg_tab
-> Foreign Scan on fpagg_tab_p1 pagg_tab -> Partial GroupAggregate
-> Partial HashAggregate Group Key: pagg_tab_1.b
Group Key: pagg_tab_1.b -> Foreign Scan on fpagg_tab_p2 pagg_tab_1
-> Foreign Scan on fpagg_tab_p2 pagg_tab_1 -> Partial GroupAggregate
-> Partial HashAggregate Group Key: pagg_tab_2.b
Group Key: pagg_tab_2.b -> Foreign Scan on fpagg_tab_p3 pagg_tab_2
-> Foreign Scan on fpagg_tab_p3 pagg_tab_2 (14 rows)
(15 rows)
-- =================================================================== -- ===================================================================
-- access rights and superuser -- access rights and superuser

View File

@ -57,7 +57,7 @@ PG_MODULE_MAGIC;
#define DEFAULT_FDW_STARTUP_COST 100.0 #define DEFAULT_FDW_STARTUP_COST 100.0
/* Default CPU cost to process 1 row (above and beyond cpu_tuple_cost). */ /* Default CPU cost to process 1 row (above and beyond cpu_tuple_cost). */
#define DEFAULT_FDW_TUPLE_COST 0.01 #define DEFAULT_FDW_TUPLE_COST 0.2
/* If no remote estimates, assume a sort costs 20% extra */ /* If no remote estimates, assume a sort costs 20% extra */
#define DEFAULT_FDW_SORT_MULTIPLIER 1.2 #define DEFAULT_FDW_SORT_MULTIPLIER 1.2