agora inbox for [email protected]
help / color / mirror / Atom feedFrom: Etsuro Fujita <[email protected]>
Subject: [PATCH 2/3] Refactor create_limit_path() to share cost adjustment code
Date: Wed, 6 Mar 2019 20:28:18 +0900
---
src/backend/optimizer/util/pathnode.c | 87 +++++++++++++++++----------
src/include/optimizer/pathnode.h | 3 +
2 files changed, 58 insertions(+), 32 deletions(-)
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c
index 169e51e792..9fd0ea4aba 100644
--- a/src/backend/optimizer/util/pathnode.c
+++ b/src/backend/optimizer/util/pathnode.c
@@ -3550,17 +3550,42 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
/*
* Adjust the output rows count and costs according to the offset/limit.
- * This is only a cosmetic issue if we are at top level, but if we are
- * building a subquery then it's important to report correct info to the
- * outer planner.
- *
- * When the offset or count couldn't be estimated, use 10% of the
- * estimated number of rows emitted from the subpath.
- *
- * XXX we don't bother to add eval costs of the offset/limit expressions
- * themselves to the path costs. In theory we should, but in most cases
- * those expressions are trivial and it's just not worth the trouble.
*/
+ adjust_limit_rows_costs(&pathnode->path.rows,
+ &pathnode->path.startup_cost,
+ &pathnode->path.total_cost,
+ offset_est, count_est);
+
+ return pathnode;
+}
+
+/*
+ * adjust_limit_rows_costs
+ * Adjust the size and cost estimates for a LimitPath node according to the
+ * offset/limit.
+ *
+ * This is only a cosmetic issue if we are at top level, but if we are
+ * building a subquery then it's important to report correct info to the outer
+ * planner.
+ *
+ * When the offset or count couldn't be estimated, use 10% of the estimated
+ * number of rows emitted from the subpath.
+ *
+ * XXX we don't bother to add eval costs of the offset/limit expressions
+ * themselves to the path costs. In theory we should, but in most cases those
+ * expressions are trivial and it's just not worth the trouble.
+ */
+void
+adjust_limit_rows_costs(double *rows, /* in/out parameter */
+ Cost *startup_cost, /* in/out parameter */
+ Cost *total_cost, /* in/out parameter */
+ int64 offset_est,
+ int64 count_est)
+{
+ double input_rows = *rows;
+ Cost input_startup_cost = *startup_cost;
+ Cost input_total_cost = *total_cost;
+
if (offset_est != 0)
{
double offset_rows;
@@ -3568,16 +3593,16 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
if (offset_est > 0)
offset_rows = (double) offset_est;
else
- offset_rows = clamp_row_est(subpath->rows * 0.10);
- if (offset_rows > pathnode->path.rows)
- offset_rows = pathnode->path.rows;
- if (subpath->rows > 0)
- pathnode->path.startup_cost +=
- (subpath->total_cost - subpath->startup_cost)
- * offset_rows / subpath->rows;
- pathnode->path.rows -= offset_rows;
- if (pathnode->path.rows < 1)
- pathnode->path.rows = 1;
+ offset_rows = clamp_row_est(input_rows * 0.10);
+ if (offset_rows > *rows)
+ offset_rows = *rows;
+ if (input_rows > 0)
+ *startup_cost +=
+ (input_total_cost - input_startup_cost)
+ * offset_rows / input_rows;
+ *rows -= offset_rows;
+ if (*rows < 1)
+ *rows = 1;
}
if (count_est != 0)
@@ -3587,19 +3612,17 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel,
if (count_est > 0)
count_rows = (double) count_est;
else
- count_rows = clamp_row_est(subpath->rows * 0.10);
- if (count_rows > pathnode->path.rows)
- count_rows = pathnode->path.rows;
- if (subpath->rows > 0)
- pathnode->path.total_cost = pathnode->path.startup_cost +
- (subpath->total_cost - subpath->startup_cost)
- * count_rows / subpath->rows;
- pathnode->path.rows = count_rows;
- if (pathnode->path.rows < 1)
- pathnode->path.rows = 1;
+ count_rows = clamp_row_est(input_rows * 0.10);
+ if (count_rows > *rows)
+ count_rows = *rows;
+ if (input_rows > 0)
+ *total_cost = *startup_cost +
+ (input_total_cost - input_startup_cost)
+ * count_rows / input_rows;
+ *rows = count_rows;
+ if (*rows < 1)
+ *rows = 1;
}
-
- return pathnode;
}
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 574bb85b50..95609aad53 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -265,6 +265,9 @@ extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel,
Path *subpath,
Node *limitOffset, Node *limitCount,
int64 offset_est, int64 count_est);
+extern void adjust_limit_rows_costs(double *rows,
+ Cost *startup_cost, Cost *total_cost,
+ int64 offset_est, int64 count_est);
extern Path *reparameterize_path(PlannerInfo *root, Path *path,
Relids required_outer,
--
2.19.2
--------------060600050702040203040200
Content-Type: text/x-patch;
name="v5-0003-postgres_fdw-Perform-UPPERREL_FINAL-step-remotely.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename*0="v5-0003-postgres_fdw-Perform-UPPERREL_FINAL-step-remotely.pa";
filename*1="tch"
view thread (13+ messages) latest in thread
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected]
Subject: Re: [PATCH 2/3] Refactor create_limit_path() to share cost adjustment code
In-Reply-To: <no-message-id-1883594@localhost>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox