diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 60b0fcfb6be..8e8be605aed 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -163,7 +163,7 @@ bool enable_parallel_hash = true; bool enable_partition_pruning = true; bool enable_presorted_aggregate = true; bool enable_async_append = true; - +bool enable_limit_adjust_cost = true; typedef struct { PlannerInfo *root; diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c index 64605be3178..510941feac0 100644 --- a/src/backend/optimizer/plan/planagg.c +++ b/src/backend/optimizer/plan/planagg.c @@ -412,12 +412,20 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, Int64GetDatum(1), false, FLOAT8PASSBYVAL); - /* - * Generate the best paths for this query, telling query_planner that we - * have LIMIT 1. - */ - subroot->tuple_fraction = 1.0; - subroot->limit_tuples = 1.0; + if (enable_limit_adjust_cost) + { + /* + * Generate the best paths for this query, telling query_planner that + * we have LIMIT 1. + */ + subroot->tuple_fraction = 1.0; + subroot->limit_tuples = 1.0; + } + else + { + subroot->tuple_fraction = 0.0; + subroot->limit_tuples = -1.0; + } final_rel = query_planner(subroot, minmax_qp_callback, NULL); @@ -432,9 +440,11 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, /* * Get the best presorted path, that being the one that's cheapest for - * fetching just one row. If there's no such path, fail. + * fetching just one row. If there's no such path, fail. If the + * adjustance of path cost is disabled, we will also set path_fraction + * to 1.0. */ - if (final_rel->rows > 1.0) + if (enable_limit_adjust_cost && final_rel->rows > 1.0) path_fraction = 1.0 / final_rel->rows; else path_fraction = 1.0; diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 566ce5b3cb4..bb6fc47be61 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -1401,12 +1401,25 @@ grouping_planner(PlannerInfo *root, double tuple_fraction, tuple_fraction = preprocess_limit(root, tuple_fraction, &offset_est, &count_est); - /* - * If we have a known LIMIT, and don't have an unknown OFFSET, we can - * estimate the effects of using a bounded sort. - */ - if (count_est > 0 && offset_est >= 0) - limit_tuples = (double) count_est + (double) offset_est; + if (enable_limit_adjust_cost) + { + /* + * If we have a known LIMIT, and don't have an unknown OFFSET, we + * can estimate the effects of using a bounded sort. + */ + if (count_est > 0 && offset_est >= 0) + limit_tuples = (double) count_est + (double) offset_est; + } + else + { + /* + * Disable limit clause adjust cost, retrival all tuples. + * offset_est and count_est are needed to adjust estimated rows of + * limit path. Thus, we should do this after calling + * preprocess_limit(). + */ + tuple_fraction = 0.0; + } } /* Make tuple_fraction accessible to lower-level routines */ diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 93e73cb44db..2f8465d0435 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -4079,6 +4079,13 @@ adjust_limit_rows_costs(double *rows, /* in/out parameter */ if (*rows < 1) *rows = 1; } + + /* disable cost modification */ + if (!enable_limit_adjust_cost) + { + *startup_cost = input_startup_cost; + *total_cost = input_total_cost; + } } diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 60b12446a1c..3a46ca17a80 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -1036,6 +1036,16 @@ struct config_bool ConfigureNamesBool[] = true, NULL, NULL, NULL }, + { + {"enable_limit_adjust_cost", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enable the planner's use of limit information adjust cost."), + NULL, + GUC_EXPLAIN + }, + &enable_limit_adjust_cost, + true, + NULL, NULL, NULL + }, { {"geqo", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("Enables genetic query optimization."), diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index c5987440817..7cdac2ec0e6 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -71,6 +71,7 @@ extern PGDLLIMPORT bool enable_partition_pruning; extern PGDLLIMPORT bool enable_presorted_aggregate; extern PGDLLIMPORT bool enable_async_append; extern PGDLLIMPORT int constraint_exclusion; +extern PGDLLIMPORT bool enable_limit_adjust_cost; extern double index_pages_fetched(double tuples_fetched, BlockNumber pages, double index_pages, PlannerInfo *root);