From 3b47aa7ccdebf0ed0b0ae987fe72e2db80bcc430 Mon Sep 17 00:00:00 2001 From: Larry955 <1412857955@qq.com> Date: Thu, 9 Mar 2023 12:44:37 +0000 Subject: [PATCH] disable hash groupby bypass path when estimiate stat --- src/objit/include/objit/common/ob_item_type.h | 1 + src/share/stat/ob_basic_stats_estimator.cpp | 6 +++--- src/share/stat/ob_hybrid_hist_estimator.cpp | 4 ++++ src/sql/optimizer/ob_log_plan.cpp | 4 +++- src/sql/parser/sql_parser_mysql_mode.l | 1 + src/sql/parser/sql_parser_mysql_mode.y | 6 +++++- src/sql/resolver/dml/ob_dml_resolver.cpp | 6 ++++++ src/sql/resolver/dml/ob_hint.cpp | 5 +++++ src/sql/resolver/dml/ob_hint.h | 6 +++++- 9 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/objit/include/objit/common/ob_item_type.h b/src/objit/include/objit/common/ob_item_type.h index efd69f0f1b..5cb28f6b09 100755 --- a/src/objit/include/objit/common/ob_item_type.h +++ b/src/objit/include/objit/common/ob_item_type.h @@ -1271,6 +1271,7 @@ typedef enum ObItemType T_GATHER_OPTIMIZER_STATISTICS, T_NO_GATHER_OPTIMIZER_STATISTICS, T_APPEND, + T_DBMS_STATS, T_KILL, T_HELP, diff --git a/src/share/stat/ob_basic_stats_estimator.cpp b/src/share/stat/ob_basic_stats_estimator.cpp index 831711a655..53a1331eb2 100644 --- a/src/share/stat/ob_basic_stats_estimator.cpp +++ b/src/share/stat/ob_basic_stats_estimator.cpp @@ -47,7 +47,7 @@ int ObBasicStatsEstimator::estimate(const ObTableStatParam ¶m, { int ret = OB_SUCCESS; const ObIArray &column_params = param.column_params_; - ObString no_rewrite("NO_REWRITE"); + ObString hint_str("NO_REWRITE USE_PLAN_CACHE(NONE) DBMS_STATS"); ObString calc_part_id_str; ObOptTableStat tab_stat; ObOptStat src_opt_stat; @@ -68,8 +68,8 @@ int ObBasicStatsEstimator::estimate(const ObTableStatParam ¶m, column_params.count(), src_col_stats))) { LOG_WARN("failed init col stats", K(ret)); - } else if (OB_FAIL(add_hint(no_rewrite, allocator))) { - LOG_WARN("failed to add no_rewrite", K(ret)); + } else if (OB_FAIL(add_hint(hint_str, allocator))) { + LOG_WARN("failed to add hint", K(ret)); } else if (OB_FAIL(add_from_table(param.db_name_, param.tab_name_))) { LOG_WARN("failed to add from table", K(ret)); } else if (OB_FAIL(fill_parallel_info(allocator, param.degree_))) { diff --git a/src/share/stat/ob_hybrid_hist_estimator.cpp b/src/share/stat/ob_hybrid_hist_estimator.cpp index 80c1c4544d..386f50dd12 100644 --- a/src/share/stat/ob_hybrid_hist_estimator.cpp +++ b/src/share/stat/ob_hybrid_hist_estimator.cpp @@ -46,6 +46,7 @@ int ObHybridHistEstimator::add_stat_item(const T &item, ObIArray & // select hybrid_hist(c1,20),hybrid_hist(c2,20),.... from t1 partition(p1) simple ... // union all // select hybrid_hist(c1,20),hybrid_hist(c2,20),.... from t1 partition(p2) simple ... +// no need to hit plan cache or rewrite int ObHybridHistEstimator::estimate(const ObTableStatParam ¶m, ObExtraParam &extra, ObIArray &dst_opt_stats) @@ -314,10 +315,13 @@ int ObHybridHistEstimator::gen_query_sql(ObIAllocator &allocator, reset_select_items(); sample_hint_ = simple_hint; int64_t duration_time = -1; + ObString hint_str("NO_REWRITE USE_PLAN_CACHE(NONE) DBMS_STATS"); //add select items if (OB_ISNULL(dst_opt_stat.table_stat_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(dst_opt_stat.table_stat_)); + } else if (OB_FAIL(add_hint(hint_str, allocator))) { + LOG_WARN("failed to add hint"); } else if (OB_FAIL(add_stat_item(ObPartitionId(¶m, src_opt_stat.table_stat_, empty_str, dst_opt_stat.table_stat_->get_partition_id()), stat_items))) { diff --git a/src/sql/optimizer/ob_log_plan.cpp b/src/sql/optimizer/ob_log_plan.cpp index 9183378cc0..fb126d686a 100644 --- a/src/sql/optimizer/ob_log_plan.cpp +++ b/src/sql/optimizer/ob_log_plan.cpp @@ -8027,6 +8027,8 @@ int ObLogPlan::allocate_group_by_as_top(ObLogicalOperator *&top, ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("failed to allocate group by operator", K(ret)); } else { + const ObGlobalHint &global_hint = get_optimizer_context().get_global_hint(); + bool has_dbms_stats = global_hint.has_dbms_stats_hint(); group_by->set_child(ObLogicalOperator::first_child, top); group_by->set_algo_type(algo); group_by->set_from_pivot(from_pivot); @@ -8036,7 +8038,7 @@ int ObLogPlan::allocate_group_by_as_top(ObLogicalOperator *&top, group_by->set_origin_child_card(origin_child_card); group_by->set_rollup_status(rollup_status); group_by->set_is_partition_wise(is_partition_wise); - group_by->set_force_push_down(FORCE_GPD & get_optimizer_context().get_aggregation_optimization_settings()); + group_by->set_force_push_down((FORCE_GPD & get_optimizer_context().get_aggregation_optimization_settings()) || has_dbms_stats); if (OB_FAIL(group_by->set_group_by_exprs(group_by_exprs))) { LOG_WARN("failed to set group by columns", K(ret)); } else if (OB_FAIL(group_by->set_rollup_exprs(rollup_exprs))) { diff --git a/src/sql/parser/sql_parser_mysql_mode.l b/src/sql/parser/sql_parser_mysql_mode.l index b275785d25..beaa6d83f2 100755 --- a/src/sql/parser/sql_parser_mysql_mode.l +++ b/src/sql/parser/sql_parser_mysql_mode.l @@ -938,6 +938,7 @@ Timestamp{whitespace}?\"[^\"]*\" { } NO_GATHER_OPTIMIZER_STATISTICS { return NO_GATHER_OPTIMIZER_STATISTICS; } GATHER_OPTIMIZER_STATISTICS { return GATHER_OPTIMIZER_STATISTICS; } +DBMS_STATS { return DBMS_STATS; } LOG_LEVEL { return LOG_LEVEL; } LEADING { return LEADING_HINT; } ORDERED { return ORDERED; } diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index aac814c5fb..edf70274b1 100755 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -184,7 +184,7 @@ USE_DISTRIBUTED_DML NO_USE_DISTRIBUTED_DML // direct load data hint DIRECT // hint related to optimizer statistics -APPEND NO_GATHER_OPTIMIZER_STATISTICS GATHER_OPTIMIZER_STATISTICS +APPEND NO_GATHER_OPTIMIZER_STATISTICS GATHER_OPTIMIZER_STATISTICS DBMS_STATS // other NEG_SIGN @@ -8453,6 +8453,10 @@ READ_CONSISTENCY '(' consistency_level ')' { malloc_terminal_node($$, result->malloc_pool_, T_GATHER_OPTIMIZER_STATISTICS); } +| DBMS_STATS +{ + malloc_terminal_node($$, result->malloc_pool_, T_DBMS_STATS); +} ; transform_hint: diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index e8ea9c20ce..615cd01451 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -11746,6 +11746,12 @@ int ObDMLResolver::resolve_global_hint(const ParseNode &hint_node, } break; } + case T_DBMS_STATS: { + CHECK_HINT_PARAM(hint_node, 0) { + global_hint.set_dbms_stats(); + } + break; + } case T_DOP: { CHECK_HINT_PARAM(hint_node, 2) { if (OB_FAIL(global_hint.merge_dop_hint(static_cast(child0->value_), diff --git a/src/sql/resolver/dml/ob_hint.cpp b/src/sql/resolver/dml/ob_hint.cpp index 41663e88c4..398fa6e45b 100644 --- a/src/sql/resolver/dml/ob_hint.cpp +++ b/src/sql/resolver/dml/ob_hint.cpp @@ -304,6 +304,7 @@ void ObGlobalHint::reset() ob_ddl_schema_versions_.reuse(); enable_append_ = false; osg_hint_.flags_ = 0; + has_dbms_stats_hint_ = false; } int ObGlobalHint::merge_global_hint(const ObGlobalHint &other) @@ -329,6 +330,7 @@ int ObGlobalHint::merge_global_hint(const ObGlobalHint &other) disable_cost_based_transform_ |= other.disable_cost_based_transform_; enable_append_ |= other.enable_append_; osg_hint_.flags_ |= other.osg_hint_.flags_; + has_dbms_stats_hint_ |= other.has_dbms_stats_hint_; if (OB_FAIL(merge_monitor_hints(other.monitoring_ids_))) { LOG_WARN("failed to merge monitor hints", K(ret)); } else if (OB_FAIL(merge_dop_hint(other.dops_))) { @@ -493,6 +495,9 @@ int ObGlobalHint::print_global_hint(PlanText &plan_text, const bool ignore_paral if (OB_SUCC(ret) && OB_FAIL(osg_hint_.print_osg_hint(plan_text))) { LOG_WARN("failed to print optimizer statistics gathering hint", K(ret)); } + if (OB_SUCC(ret) && has_dbms_stats_hint()) { + PRINT_GLOBAL_HINT_STR("DBMS_STATS"); + } return ret; } diff --git a/src/sql/resolver/dml/ob_hint.h b/src/sql/resolver/dml/ob_hint.h index 5e8b52db3e..54531e52d6 100644 --- a/src/sql/resolver/dml/ob_hint.h +++ b/src/sql/resolver/dml/ob_hint.h @@ -163,6 +163,8 @@ struct ObGlobalHint { { return MIN_OUTLINE_ENABLE_VERSION <= version && CLUSTER_CURRENT_VERSION >= version; } bool disable_query_transform() const { return disable_transform_; } bool disable_cost_based_transform() const { return disable_cost_based_transform_; } + inline bool has_dbms_stats_hint() const { return has_dbms_stats_hint_; } + inline void set_dbms_stats() { has_dbms_stats_hint_ = true; } bool has_append() const { return (osg_hint_.flags_ & ObOptimizerStatisticsGatheringHint::OB_APPEND_HINT) ? true : false; } @@ -217,7 +219,8 @@ struct ObGlobalHint { K_(enable_append), K_(opt_params), K_(ob_ddl_schema_versions), - K_(osg_hint)); + K_(osg_hint), + K_(has_dbms_stats_hint)); int64_t frozen_version_; int64_t topk_precision_; int64_t sharding_minimum_row_count_; @@ -244,6 +247,7 @@ struct ObGlobalHint { ObOptParamHint opt_params_; common::ObSArray ob_ddl_schema_versions_; ObOptimizerStatisticsGatheringHint osg_hint_; + bool has_dbms_stats_hint_; }; // used in physical plan