From f44ad3589b33b7fd98058e98cd57b8b9eba466ef Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 25 Apr 2001 22:04:37 +0000 Subject: [PATCH] Tweak nestloop costing to weight restart cost of inner path more heavily. Without this, it was making some pretty silly decisions about whether an expensive sub-SELECT should be the inner or outer side of a join... --- src/backend/optimizer/path/costsize.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 710a441576..dc5fe8349e 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -443,14 +443,22 @@ cost_nestloop(Path *path, /* cost of source data */ /* - * NOTE: we assume that the inner path's startup_cost is paid once, - * not over again on each restart. This is certainly correct if the - * inner path is materialized. Are there any cases where it is wrong? + * NOTE: clearly, we must pay both outer and inner paths' startup_cost + * before we can start returning tuples, so the join's startup cost + * is their sum. What's not so clear is whether the inner path's + * startup_cost must be paid again on each rescan of the inner path. + * This is not true if the inner path is materialized, but probably + * is true otherwise. Since we don't yet have clean handling of the + * decision whether to materialize a path, we can't tell here which + * will happen. As a compromise, charge 50% of the inner startup cost + * for each restart. */ startup_cost += outer_path->startup_cost + inner_path->startup_cost; run_cost += outer_path->total_cost - outer_path->startup_cost; run_cost += outer_path->parent->rows * (inner_path->total_cost - inner_path->startup_cost); + if (outer_path->parent->rows > 1) + run_cost += (outer_path->parent->rows - 1) * inner_path->startup_cost; /* * Number of tuples processed (not number emitted!). If inner path is -- 2.39.5