diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 1e4d404f02..9b189de91d 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -123,6 +123,7 @@ double cpu_index_tuple_cost = DEFAULT_CPU_INDEX_TUPLE_COST; double cpu_operator_cost = DEFAULT_CPU_OPERATOR_COST; double parallel_tuple_cost = DEFAULT_PARALLEL_TUPLE_COST; double parallel_setup_cost = DEFAULT_PARALLEL_SETUP_COST; +double recursive_worktable_estimate = DEFAULT_RECURSIVE_WORKTABLE_ESTIMATE; int effective_cache_size = DEFAULT_EFFECTIVE_CACHE_SIZE; @@ -5659,10 +5660,11 @@ set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel, double cte_rows) if (rte->self_reference) { /* - * In a self-reference, arbitrarily assume the average worktable size - * is about 10 times the nonrecursive term's size. + * Use recursive_worktable_estimate to get average size of worktable, + * across all iterations. This will vary depending upon how bushy the + * data is, so allow the user to set based upon their data. */ - rel->tuples = 10 * cte_rows; + rel->tuples = recursive_worktable_estimate * cte_rows; } else { diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index d2ce4a8450..c84643bc0d 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -3702,6 +3702,19 @@ static struct config_real ConfigureNamesReal[] = NULL, NULL, NULL }, + { + {"recursive_worktable_estimate", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Sets the planner's estimate of the size of " + "the recursive_worktable as a multiple of the " + "initial non-recursive query size."), + NULL, + GUC_EXPLAIN + }, + &recursive_worktable_estimate, + DEFAULT_RECURSIVE_WORKTABLE_ESTIMATE, 0.0, 1000000.0, + NULL, NULL, NULL + }, + { {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("GEQO: selective pressure within the population."), diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index 2113bc82de..9af7a6eea3 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -29,6 +29,8 @@ #define DEFAULT_PARALLEL_TUPLE_COST 0.1 #define DEFAULT_PARALLEL_SETUP_COST 1000.0 +#define DEFAULT_RECURSIVE_WORKTABLE_ESTIMATE 10.0 + #define DEFAULT_EFFECTIVE_CACHE_SIZE 524288 /* measured in pages */ typedef enum diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h index 41b49b2662..eccac5039f 100644 --- a/src/include/optimizer/optimizer.h +++ b/src/include/optimizer/optimizer.h @@ -92,6 +92,7 @@ extern PGDLLIMPORT double cpu_operator_cost; extern PGDLLIMPORT double parallel_tuple_cost; extern PGDLLIMPORT double parallel_setup_cost; extern PGDLLIMPORT int effective_cache_size; +extern PGDLLIMPORT double recursive_worktable_estimate; extern double clamp_row_est(double nrows);