[CP] [CP] add a parameter to control multi version batch rescan scenarios
This commit is contained in:
parent
214dcc5a87
commit
4270b894e9
@ -1566,6 +1566,12 @@ DEF_BOOL(_enable_das_keep_order, OB_TENANT_PARAMETER, "True",
|
||||
DEF_BOOL(_enable_nlj_spf_use_rich_format, OB_TENANT_PARAMETER, "True",
|
||||
"enable nlj and spf use rich format",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
DEF_BOOL(_enable_distributed_das_scan, OB_TENANT_PARAMETER, "True",
|
||||
"enable distributed DAS scan",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
DEF_INT(_enable_das_batch_rescan_flag, OB_TENANT_PARAMETER, "0",
|
||||
"enable das batch rescan for multiple scenarios.",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
DEF_INT(_parallel_max_active_sessions, OB_TENANT_PARAMETER, "0", "[0,]",
|
||||
"max active parallel sessions allowed for tenant. Range: [0,+∞)",
|
||||
|
@ -1572,6 +1572,10 @@ int ObJoinOrder::will_use_das(const uint64_t table_id,
|
||||
LOG_WARN("failed to check hint use das", K(ret));
|
||||
} else if (create_das_path || create_basic_path) {
|
||||
LOG_TRACE("will use das by hint", K(create_das_path), K(create_basic_path));
|
||||
} else if (OB_UNLIKELY(!get_plan()->get_optimizer_context().is_enable_distributed_das_scan())) {
|
||||
create_das_path = false;
|
||||
create_basic_path = true;
|
||||
LOG_TRACE("disable das scan by tenant config", K(create_das_path), K(create_basic_path));
|
||||
} else if (OB_FAIL(check_opt_rule_use_das(table_id,
|
||||
index_id,
|
||||
index_info_cache,
|
||||
@ -6875,8 +6879,6 @@ int AccessPath::compute_access_path_batch_rescan()
|
||||
can_batch_rescan = false;
|
||||
} else if (order_direction_ != default_asc_direction() && order_direction_ != ObOrderDirection::UNORDERED) {
|
||||
can_batch_rescan = false;
|
||||
} else if (plan->get_optimizer_context().enable_experimental_batch_rescan()) {
|
||||
can_batch_rescan = true;
|
||||
} else if (est_cost_info_.index_meta_info_.is_global_index_ &&
|
||||
est_cost_info_.index_meta_info_.is_index_back_ &&
|
||||
OB_FAIL(ObOptimizerUtil::get_has_global_index_filters(plan->get_optimizer_context().get_sql_schema_guard(),
|
||||
@ -6886,8 +6888,8 @@ int AccessPath::compute_access_path_batch_rescan()
|
||||
has_index_lookup_filter))) {
|
||||
LOG_WARN("failed to get has global index filters", K(ret));
|
||||
} else {
|
||||
// For the global index lookup, if there is a pushdown filter when scanning the index, batch cannot be used.
|
||||
can_batch_rescan = !has_index_scan_filter;
|
||||
// batch rescan when global lookup has index pushdown filter, enabled after 4.2.1.9.
|
||||
can_batch_rescan = !has_index_scan_filter || plan->get_optimizer_context().enable_global_index_filter_batch();
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -7002,7 +7004,7 @@ int AccessPath::compute_is_das_dynamic_part_pruning(const EqualSets &equal_sets,
|
||||
|| OB_ISNULL(table_partition_info_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected params", K(ret), K(parent_), K(table_partition_info_));
|
||||
} else if (!parent_->get_plan()->get_optimizer_context().enable_425_batch_rescan()) {
|
||||
} else if (!parent_->get_plan()->get_optimizer_context().enable_425_opt_batch_rescan()) {
|
||||
can_das_dynamic_part_pruning_ = false;
|
||||
} else if (table_partition_info_->get_phy_tbl_location_info().get_partition_cnt() <= 1) {
|
||||
can_das_dynamic_part_pruning_ = false;
|
||||
@ -7964,8 +7966,8 @@ int JoinPath::compute_nlj_batch_rescan()
|
||||
/* join type not support */
|
||||
} else if (!right_path_->subquery_exprs_.empty()) {
|
||||
/* subplan filter allocated for on condition subquery, not support */
|
||||
} else if (IS_SEMI_ANTI_JOIN(join_type_) && !plan->get_optimizer_context().enable_experimental_batch_rescan()) {
|
||||
/* semi/anti join not support */
|
||||
} else if (IS_SEMI_ANTI_JOIN(join_type_) && !plan->get_optimizer_context().enable_semi_anti_join_batch()) {
|
||||
/* semi/anti join batch, enabled after 4.2.5 */
|
||||
} else if (OB_FAIL(check_right_has_gi_or_exchange(right_has_gi_or_exchange))) {
|
||||
LOG_WARN("failed to check right has gi or exchange", K(ret));
|
||||
} else if (right_has_gi_or_exchange) {
|
||||
@ -7973,20 +7975,22 @@ int JoinPath::compute_nlj_batch_rescan()
|
||||
} else if (right_path_->is_access_path()) {
|
||||
const AccessPath *ap = static_cast<const AccessPath*>(right_path_);
|
||||
can_use_batch_nlj_ = ap->can_batch_rescan_;
|
||||
if (can_use_batch_nlj_ && !plan->get_optimizer_context().enable_experimental_batch_rescan()
|
||||
&& OB_FAIL(ObOptimizerUtil::check_exec_param_filter_exprs(ap->est_cost_info_.pushdown_prefix_filters_,
|
||||
right_path_->nl_params_,
|
||||
can_use_batch_nlj_))) {
|
||||
LOG_WARN("failed to check exec param filter exprs", K(ret));
|
||||
if (can_use_batch_nlj_ && !plan->get_optimizer_context().enable_non_prefix_exec_param_batch()) {
|
||||
if (OB_FAIL(ObOptimizerUtil::check_exec_param_filter_exprs(ap->est_cost_info_.pushdown_prefix_filters_,
|
||||
right_path_->nl_params_,
|
||||
can_use_batch_nlj_))) {
|
||||
LOG_WARN("failed to check exec param filter exprs", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (!right_path_->is_subquery_path()) {
|
||||
/* do nothing, only access_path and subquery_path may use batch nlj */
|
||||
} else if (plan->get_optimizer_context().enable_experimental_batch_rescan() &&
|
||||
} else if (plan->get_optimizer_context().enable_425_exec_batch_rescan() &&
|
||||
OB_FAIL(ObOptimizerUtil::check_can_batch_rescan(static_cast<const SubQueryPath*>(right_path_)->root_,
|
||||
false,
|
||||
right_path_->nl_params_,
|
||||
true,
|
||||
can_use_batch_nlj_))) {
|
||||
LOG_WARN("failed to check plan can batch rescan", K(ret));
|
||||
} else if (!plan->get_optimizer_context().enable_experimental_batch_rescan() &&
|
||||
} else if (!plan->get_optimizer_context().enable_425_exec_batch_rescan() &&
|
||||
OB_FAIL(ObOptimizerUtil::check_can_batch_rescan_compat(static_cast<const SubQueryPath*>(right_path_)->root_,
|
||||
right_path_->nl_params_,
|
||||
true,
|
||||
|
@ -2554,7 +2554,7 @@ int ObLogPlan::init_rescan_info_for_query_ref(const ObLogPlan &parent_plan,
|
||||
is_rescan_subplan_ = parent_plan.is_rescan_subplan_ || is_rescan_subquery;
|
||||
disable_child_batch_rescan_ = parent_plan.disable_child_batch_rescan_
|
||||
|| (is_rescan_subquery
|
||||
&& !get_optimizer_context().enable_experimental_batch_rescan());
|
||||
&& !get_optimizer_context().enable_spf_semi_anti_child_batch());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2566,7 +2566,7 @@ int ObLogPlan::init_rescan_info_for_subquery_paths(const ObLogPlan &parent_plan,
|
||||
is_rescan_subplan_ = parent_plan.is_rescan_subplan_ || is_inner_path;
|
||||
disable_child_batch_rescan_ = parent_plan.disable_child_batch_rescan_
|
||||
|| (is_semi_anti_join_inner_path
|
||||
&& !get_optimizer_context().enable_experimental_batch_rescan());
|
||||
&& !get_optimizer_context().enable_spf_semi_anti_child_batch());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -462,10 +462,10 @@ int ObLogSubPlanFilter::compute_spf_batch_rescan()
|
||||
/* subplan filter group rescan is disabled */
|
||||
} else if (get_plan()->get_disable_child_batch_rescan()) {
|
||||
/* do nothing */
|
||||
} else if (get_plan()->get_optimizer_context().enable_experimental_batch_rescan()
|
||||
} else if (get_plan()->get_optimizer_context().enable_425_exec_batch_rescan()
|
||||
&& OB_FAIL(compute_spf_batch_rescan(can_batch))) {
|
||||
LOG_WARN("failed to compute group rescan", K(ret));
|
||||
} else if (!get_plan()->get_optimizer_context().enable_experimental_batch_rescan()
|
||||
} else if (!get_plan()->get_optimizer_context().enable_425_exec_batch_rescan()
|
||||
&& OB_FAIL(compute_spf_batch_rescan_compat(can_batch))) {
|
||||
LOG_WARN("failed to compute group rescan compat", K(ret));
|
||||
} else {
|
||||
@ -482,19 +482,34 @@ int ObLogSubPlanFilter::compute_spf_batch_rescan(bool &can_batch)
|
||||
const ObShardingInfo *sharding = NULL;
|
||||
const ObLogicalOperator *child = NULL;
|
||||
const ObDMLStmt *stmt = NULL;
|
||||
const ObLogPlan *plan = NULL;
|
||||
bool has_ref_assign_user_var = false;
|
||||
bool left_allocated_exchange = false;
|
||||
bool right_allocated_exchange = false;
|
||||
bool has_rescan_subquery = false;
|
||||
// check if exec params contain rownum
|
||||
if (OB_ISNULL(plan = get_plan())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(plan));
|
||||
} else if ((!init_plan_idxs_.is_empty() || !one_time_idxs_.is_empty()) &&
|
||||
!plan->get_optimizer_context().enable_onetime_initplan_batch()) {
|
||||
/* spf contains onetime expr or init plan, enabled after 4.2.5 */
|
||||
can_batch = false;
|
||||
}
|
||||
|
||||
// check if exec params contain sub_query/rownum
|
||||
for (int64_t i = 0; OB_SUCC(ret) && can_batch && i < exec_params_.count(); i++) {
|
||||
if (OB_ISNULL(exec_params_.at(i)) || OB_ISNULL(ref_expr = exec_params_.at(i)->get_ref_expr())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(i), K(ref_expr), KPC(exec_params_.at(i)));
|
||||
} else {
|
||||
can_batch = !ref_expr->has_flag(CNT_ROWNUM);
|
||||
can_batch &= !ref_expr->has_flag(CNT_ROWNUM);
|
||||
if (can_batch && !plan->get_optimizer_context().enable_contains_subquery_batch()) {
|
||||
can_batch &= !ref_expr->has_flag(CNT_SUB_QUERY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if child can batch rescan
|
||||
for (int64_t i = 0; OB_SUCC(ret) && can_batch && i < get_num_of_child(); i++) {
|
||||
if (OB_ISNULL(child = get_child(i)) || OB_ISNULL(sharding = child->get_sharding())
|
||||
|| OB_ISNULL(stmt= child->get_stmt())) {
|
||||
@ -504,7 +519,7 @@ int ObLogSubPlanFilter::compute_spf_batch_rescan(bool &can_batch)
|
||||
left_allocated_exchange = child->is_exchange_allocated();
|
||||
} else if (init_plan_idxs_.has_member(i) || one_time_idxs_.has_member(i)) {
|
||||
can_batch = sharding->is_single();
|
||||
} else if (OB_FAIL(ObOptimizerUtil::check_can_batch_rescan(child, true, can_batch))) {
|
||||
} else if (OB_FAIL(ObOptimizerUtil::check_can_batch_rescan(child, exec_params_, false, can_batch))) {
|
||||
LOG_WARN("failed to check plan can batch rescan", K(ret));
|
||||
} else if (OB_FAIL(stmt->has_ref_assign_user_var(has_ref_assign_user_var))) {
|
||||
LOG_WARN("faield to check stmt has assignment ref user var", K(ret));
|
||||
|
@ -1694,7 +1694,7 @@ int ObOptEstCostModel::calc_das_rpc_cost(const ObCostTableScanInfo &est_cost_inf
|
||||
if (OB_ISNULL(est_cost_info.sel_ctx_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret), K(est_cost_info.sel_ctx_));
|
||||
} else if (!est_cost_info.sel_ctx_->get_opt_ctx().enable_425_batch_rescan()) {
|
||||
} else if (!est_cost_info.sel_ctx_->get_opt_ctx().enable_425_opt_batch_rescan()) {
|
||||
/* do nothing */
|
||||
} else if (!est_cost_info.is_das_scan_ || !est_cost_info.is_rescan_) {
|
||||
/* do nothing */
|
||||
|
@ -702,6 +702,8 @@ int ObOptimizer::extract_opt_ctx_basic_flags(const ObDMLStmt &stmt, ObSQLSession
|
||||
bool better_inlist_costing = false;
|
||||
bool enable_spf_batch_rescan = session.is_spf_mlj_group_rescan_enabled();
|
||||
bool enable_px_ordered_coord = GCONF._enable_px_ordered_coord;
|
||||
int64_t das_batch_rescan_flag = tenant_config.is_valid() ? tenant_config->_enable_das_batch_rescan_flag : 0;
|
||||
bool enable_distributed_das_scan = tenant_config.is_valid() ? tenant_config->_enable_distributed_das_scan : true;
|
||||
const ObOptParamHint &opt_params = ctx_.get_global_hint().opt_params_;
|
||||
if (OB_ISNULL(query_ctx)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -760,9 +762,11 @@ int ObOptimizer::extract_opt_ctx_basic_flags(const ObDMLStmt &stmt, ObSQLSession
|
||||
LOG_WARN("failed to check partition wise plan enabled", K(ret));
|
||||
} else if (OB_FAIL(opt_params.get_bool_opt_param(ObOptParamHint::ENABLE_PX_ORDERED_COORD, enable_px_ordered_coord))) {
|
||||
LOG_WARN("failed to get opt param enable px ordered coord", K(ret));
|
||||
} else if (OB_FAIL(opt_params.get_integer_opt_param(ObOptParamHint::DAS_BATCH_RESCAN_FLAG, das_batch_rescan_flag))) {
|
||||
LOG_WARN("failed to get das batch rescan flag", K(ret));
|
||||
} else {
|
||||
ctx_.init_batch_rescan_flags(enable_use_batch_nlj, enable_spf_batch_rescan,
|
||||
query_ctx->optimizer_features_enable_version_);
|
||||
query_ctx->optimizer_features_enable_version_, das_batch_rescan_flag);
|
||||
ctx_.set_storage_estimation_enabled(storage_estimation_enabled);
|
||||
ctx_.set_serial_set_order(force_serial_set_order);
|
||||
ctx_.set_has_multiple_link_stmt(link_stmt_count > 1);
|
||||
@ -778,6 +782,7 @@ int ObOptimizer::extract_opt_ctx_basic_flags(const ObDMLStmt &stmt, ObSQLSession
|
||||
ctx_.set_enable_better_inlist_costing(better_inlist_costing);
|
||||
ctx_.set_push_join_pred_into_view_enabled(push_join_pred_into_view_enabled);
|
||||
ctx_.set_enable_px_ordered_coord(enable_px_ordered_coord);
|
||||
ctx_.set_enable_distributed_das_scan(enable_distributed_das_scan);
|
||||
if (!hash_join_enabled
|
||||
&& !optimizer_sortmerge_join_enabled
|
||||
&& !nested_loop_join_enabled) {
|
||||
|
@ -271,7 +271,8 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
|
||||
enable_new_query_range_(false),
|
||||
partition_wise_plan_enabled_(true),
|
||||
enable_px_ordered_coord_(false),
|
||||
enable_opt_row_goal_(ObEnableOptRowGoal::MAX)
|
||||
enable_opt_row_goal_(ObEnableOptRowGoal::MAX),
|
||||
enable_distributed_das_scan_(true)
|
||||
{ }
|
||||
inline common::ObOptStatManager *get_opt_stat_manager() { return opt_stat_manager_; }
|
||||
inline void set_opt_stat_manager(common::ObOptStatManager *sm) { opt_stat_manager_ = sm; }
|
||||
@ -437,20 +438,80 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
|
||||
return enable_px_batch_rescan_;
|
||||
}
|
||||
|
||||
static const int BATCH_RESCAN_BIT_GLOBAL_INDEX_FILTER = 0;
|
||||
static const int BATCH_RESCAN_BIT_SPF_SEMI_ANTI_LEFT_CHILD = 1;
|
||||
static const int BATCH_RESCAN_BIT_SPF_SEMI_ANTI_CHILD = 2;
|
||||
static const int BATCH_RESCAN_BIT_SEMI_ANTI_JOIN = 3;
|
||||
static const int BATCH_RESCAN_BIT_LIMIT_PUSHDOWN = 4;
|
||||
static const int BATCH_RESCAN_BIT_NON_PREFIX_EXEC_PARAM = 5;
|
||||
static const int BATCH_RESCAN_BIT_NORMAL_SCAN = 6;
|
||||
static const int BATCH_RESCAN_BIT_ONETIME_INITPLAN = 7;
|
||||
static const int BATCH_RESCAN_BIT_CONTAINS_SUBQUERY = 8;
|
||||
static const int BATCH_RESCAN_BIT_NON_BASIC_SCAN = 9;
|
||||
static const int BATCH_RESCAN_BIT_STARTUP_FILTER = 10;
|
||||
|
||||
// whether batch rescan can be enabled depends on two factors:
|
||||
// 1. current version must support corresponding batch rescan scenario
|
||||
// 2. corresponding batch rescan configuration must be enabled
|
||||
void init_batch_rescan_flags(const bool enable_batch_nlj,
|
||||
const bool enable_batch_spf,
|
||||
const uint64_t opt_version)
|
||||
const uint64_t opt_version,
|
||||
const int64_t batch_rescan_flag)
|
||||
{
|
||||
enable_nlj_batch_rescan_ = enable_batch_nlj;
|
||||
enable_spf_batch_rescan_ = enable_batch_nlj && enable_batch_spf;
|
||||
// adaptive group-rescan is supported in 4.2.3.0
|
||||
enable_425_batch_rescan_ = GET_MIN_CLUSTER_VERSION() >= COMPAT_VERSION_4_2_3
|
||||
&& (opt_version >= COMPAT_VERSION_4_2_5 || opt_version >= COMPAT_VERSION_4_3_5);
|
||||
bool enable_425_opt_version = false;
|
||||
if (get_query_ctx() != nullptr) {
|
||||
enable_425_opt_version = get_query_ctx()->check_opt_compat_version(
|
||||
COMPAT_VERSION_4_2_5, COMPAT_VERSION_4_3_0, COMPAT_VERSION_4_3_5);
|
||||
}
|
||||
enable_425_opt_batch_rescan_ = enable_425_opt_version;
|
||||
enable_global_index_filter_ = opt_version > COMPAT_VERSION_4_2_1_BP8 &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_GLOBAL_INDEX_FILTER));
|
||||
enable_spf_semi_anti_left_child_ = opt_version > COMPAT_VERSION_4_2_1_BP8 &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_SPF_SEMI_ANTI_LEFT_CHILD));
|
||||
enable_spf_semi_anti_child_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_SPF_SEMI_ANTI_CHILD));
|
||||
enable_semi_anti_join_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_SEMI_ANTI_JOIN));
|
||||
enable_limit_pushdown_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_LIMIT_PUSHDOWN));
|
||||
enable_non_prefix_exec_param_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_NON_PREFIX_EXEC_PARAM));
|
||||
enable_normal_scan_ = enable_425_opt_version&&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_NORMAL_SCAN));
|
||||
enable_onetime_initplan_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_ONETIME_INITPLAN));
|
||||
enable_contains_subquery_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_CONTAINS_SUBQUERY));
|
||||
enable_non_basic_scan_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_NON_BASIC_SCAN));
|
||||
enable_startup_filter_ = enable_425_opt_version &&
|
||||
(batch_rescan_flag & (0x1L << BATCH_RESCAN_BIT_STARTUP_FILTER));
|
||||
// when enable das batch rescan flag and opt_version >= 4.2.5, use new interface to check can batch rescan,
|
||||
// otherwise, use old interface to check can batch rescan for compatibility.
|
||||
enable_425_exec_batch_rescan_ = (batch_rescan_flag != 0) && enable_425_opt_version;
|
||||
// when use tracepoint, enable all batch rescan.
|
||||
if ((OB_E(EventTable::EN_DAS_GROUP_RESCAN_TEST_MODE) OB_SUCCESS) != OB_SUCCESS) {
|
||||
batch_rescan_flags_ = INT64_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool enable_nlj_batch_rescan() const { return enable_nlj_batch_rescan_; }
|
||||
inline bool enable_spf_batch_rescan() const { return enable_spf_batch_rescan_; }
|
||||
inline bool enable_425_batch_rescan() const { return enable_425_batch_rescan_; }
|
||||
inline bool enable_experimental_batch_rescan() const { return (OB_E(EventTable::EN_DAS_GROUP_RESCAN_TEST_MODE) OB_SUCCESS) != OB_SUCCESS; }
|
||||
inline bool enable_425_opt_batch_rescan() const { return enable_425_opt_batch_rescan_; }
|
||||
inline bool enable_425_exec_batch_rescan() const { return enable_425_exec_batch_rescan_; }
|
||||
inline bool enable_global_index_filter_batch() const { return enable_global_index_filter_; }
|
||||
inline bool enable_spf_semi_anti_left_child_batch() const { return enable_spf_semi_anti_left_child_; }
|
||||
inline bool enable_spf_semi_anti_child_batch() const { return enable_spf_semi_anti_child_; }
|
||||
inline bool enable_semi_anti_join_batch() const { return enable_semi_anti_join_; }
|
||||
inline bool enable_limit_pushdown_batch() const { return enable_limit_pushdown_; }
|
||||
inline bool enable_non_prefix_exec_param_batch() const { return enable_non_prefix_exec_param_; }
|
||||
inline bool enable_normal_scan_batch() const { return enable_normal_scan_; }
|
||||
inline bool enable_onetime_initplan_batch() const { return enable_onetime_initplan_; }
|
||||
inline bool enable_contains_subquery_batch() const { return enable_contains_subquery_; }
|
||||
inline bool enable_non_basic_scan_batch() const { return enable_non_basic_scan_; }
|
||||
inline bool enable_startup_filter_batch() const { return enable_startup_filter_; }
|
||||
|
||||
int get_px_object_sample_rate()
|
||||
{
|
||||
@ -700,6 +761,8 @@ ObOptimizerContext(ObSQLSessionInfo *session_info,
|
||||
inline bool enable_new_query_range() const { return enable_new_query_range_; }
|
||||
inline void set_enable_opt_row_goal(int64_t type) { enable_opt_row_goal_ = static_cast<ObEnableOptRowGoal>(type); }
|
||||
inline ObEnableOptRowGoal get_enable_opt_row_goal() const { return enable_opt_row_goal_; }
|
||||
inline bool is_enable_distributed_das_scan() const { return enable_distributed_das_scan_; }
|
||||
inline void set_enable_distributed_das_scan(bool enabled) { enable_distributed_das_scan_ = enabled; }
|
||||
private:
|
||||
ObSQLSessionInfo *session_info_;
|
||||
ObExecContext *exec_ctx_;
|
||||
@ -740,9 +803,21 @@ private:
|
||||
union {
|
||||
int64_t batch_rescan_flags_;
|
||||
struct {
|
||||
int64_t enable_nlj_batch_rescan_ : 1; // enable nestloop inner path batch rescan
|
||||
int64_t enable_spf_batch_rescan_ : 1; // enable subplan filter batch rescan
|
||||
int64_t enable_425_batch_rescan_ : 1; // enbale batch rescan behaviors supported in 4.2.5
|
||||
int64_t enable_nlj_batch_rescan_ : 1; // enable nestloop inner path batch rescan
|
||||
int64_t enable_spf_batch_rescan_ : 1; // enable subplan filter batch rescan
|
||||
int64_t enable_425_opt_batch_rescan_ : 1; // enable optimizer batch rescan behaviors supported in 4.2.5
|
||||
int64_t enable_425_exec_batch_rescan_ : 1; // enable exec batch rescan behaviors supported in 4.2.5
|
||||
int64_t enable_global_index_filter_ : 1; // enable batch rescan when has global index filter
|
||||
int64_t enable_spf_semi_anti_left_child_ : 1; // enable batch rescan when as spf/semi-anti join left child
|
||||
int64_t enable_spf_semi_anti_child_ : 1; // enable batch rescan when as spf/semi-anti join child
|
||||
int64_t enable_semi_anti_join_ : 1; // enable semi/anti join batch rescan
|
||||
int64_t enable_limit_pushdown_ : 1; // enable batch rescan when contains limit pushdown
|
||||
int64_t enable_non_prefix_exec_param_ : 1; // enable batch rescan when no prefix exec param
|
||||
int64_t enable_normal_scan_ : 1; // enable batch rescan when use normal table scan
|
||||
int64_t enable_onetime_initplan_ : 1; // enable batch rescan when contains onetime init plan
|
||||
int64_t enable_contains_subquery_ : 1; // enable batch rescan when exec param contains subquery
|
||||
int64_t enable_non_basic_scan_ : 1; // enable batch rescan when not basic table scan/subplan scan
|
||||
int64_t enable_startup_filter_ : 1; // enable batch rescan when startup filter contains exec param
|
||||
};
|
||||
};
|
||||
common::ObSEArray<ColumnUsageArg, 16, common::ModulePageAllocator, true> column_usage_infos_;
|
||||
@ -807,6 +882,7 @@ private:
|
||||
bool partition_wise_plan_enabled_;
|
||||
bool enable_px_ordered_coord_;
|
||||
ObEnableOptRowGoal enable_opt_row_goal_;
|
||||
bool enable_distributed_das_scan_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -10295,27 +10295,67 @@ int ObOptimizerUtil::get_has_global_index_filters(const ObIArray<ObRawExpr*> &fi
|
||||
return ret;
|
||||
}
|
||||
|
||||
// check batch rescan for nlj / subplan filter
|
||||
// check batch rescan for nlj / subplan filter
|
||||
int ObOptimizerUtil::check_can_batch_rescan(const ObLogicalOperator *op,
|
||||
const bool allow_normal_scan,
|
||||
const ObIArray<ObExecParamRawExpr*> &rescan_params,
|
||||
bool for_nlj,
|
||||
bool &can_batch_rescan)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
can_batch_rescan = false;
|
||||
if (OB_ISNULL(op)) {
|
||||
bool has_exec_param = false;
|
||||
const ObLogPlan *plan = nullptr;
|
||||
if (OB_ISNULL(op) || OB_ISNULL(plan = op->get_plan())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(op));
|
||||
LOG_WARN("get unexpected null", K(ret), K(op), K(plan));
|
||||
} else if (OB_FAIL(check_exec_param_filter_exprs(op->get_startup_exprs(), has_exec_param))) {
|
||||
LOG_WARN("failed to check exec param filter exprs", K(ret));
|
||||
} else if (has_exec_param && !plan->get_optimizer_context().enable_startup_filter_batch()) {
|
||||
/* startup filter contains exec param, enabled after 4.2.5 */
|
||||
} else if ((log_op_def::LOG_LIMIT == op->get_type()
|
||||
|| (op->is_table_scan() && NULL != static_cast<const ObLogTableScan*>(op)->get_limit_expr()))
|
||||
&& !plan->get_optimizer_context().enable_limit_pushdown_batch()) {
|
||||
/* contains limit pushdown, enabled after 4.2.5 */
|
||||
} else if (op->is_table_scan()) {
|
||||
const ObLogTableScan *table_scan = static_cast<const ObLogTableScan*>(op);
|
||||
can_batch_rescan = (allow_normal_scan || table_scan->use_das()) && table_scan->can_batch_rescan();
|
||||
} else if (1 == op->get_num_of_child() || log_op_def::LOG_SET == op->get_type()) {
|
||||
can_batch_rescan = true;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && can_batch_rescan && i < op->get_num_of_child(); ++i) {
|
||||
if (OB_FAIL(SMART_CALL(check_can_batch_rescan(op->get_child(i), false, can_batch_rescan)))) {
|
||||
LOG_WARN("failed to check batch nlj", K(ret));
|
||||
if (OB_ISNULL(table_scan->get_est_cost_info())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null est cost info", K(ret));
|
||||
} else if (!table_scan->can_batch_rescan()) {
|
||||
can_batch_rescan = false;
|
||||
} else if (!table_scan->use_das() && !plan->get_optimizer_context().enable_normal_scan_batch()) {
|
||||
/* normal table scan, enabled after 4.2.5 */
|
||||
can_batch_rescan = false;
|
||||
} else if (!plan->get_optimizer_context().enable_non_prefix_exec_param_batch()) {
|
||||
if (OB_FAIL(check_exec_param_filter_exprs(table_scan->get_est_cost_info()->pushdown_prefix_filters_,
|
||||
rescan_params,
|
||||
can_batch_rescan))) {
|
||||
LOG_WARN("failed to check exec param filter exprs", K(ret));
|
||||
}
|
||||
} else {
|
||||
can_batch_rescan = true;
|
||||
}
|
||||
} else { // other multi child op use batch is disabled, multi level nlj use batch is disabled
|
||||
} else if (log_op_def::LOG_SUBPLAN_SCAN == op->get_type()) {
|
||||
if (OB_FAIL(SMART_CALL(check_can_batch_rescan(op->get_child(0), rescan_params, for_nlj, can_batch_rescan)))) {
|
||||
LOG_WARN("failed to check can batch rescan for op child", K(ret));
|
||||
}
|
||||
} else if (!for_nlj && !plan->get_optimizer_context().enable_non_basic_scan_batch()) {
|
||||
/* non table scan/subplan scan for subplan filter, enabled after 4.2.5 */
|
||||
} else if (1 == op->get_num_of_child()) {
|
||||
if (OB_FAIL(SMART_CALL(check_can_batch_rescan(op->get_child(0), rescan_params, for_nlj, can_batch_rescan)))) {
|
||||
LOG_WARN("failed to check can batch rescan for op child", K(ret));
|
||||
}
|
||||
} else if (log_op_def::LOG_SET == op->get_type()) {
|
||||
can_batch_rescan = ObSelectStmt::UNION == static_cast<const ObLogSet*>(op)->get_set_op()
|
||||
|| GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_4_3_5_0;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && can_batch_rescan && i < op->get_num_of_child(); ++i) {
|
||||
if (OB_FAIL(SMART_CALL(check_can_batch_rescan(op->get_child(i), rescan_params, for_nlj, can_batch_rescan)))) {
|
||||
LOG_WARN("failed to check batch rescan", K(ret));
|
||||
} else {/* do nothing */}
|
||||
}
|
||||
} else {
|
||||
// other multi child op use batch is disabled
|
||||
// multi level nlj use batch is disabled
|
||||
can_batch_rescan = false;
|
||||
}
|
||||
return ret;
|
||||
|
@ -1633,10 +1633,11 @@ public:
|
||||
const ObIArray<uint64_t> &index_columns,
|
||||
bool &has_index_scan_filter,
|
||||
bool &has_index_lookup_filter);
|
||||
|
||||
static int check_can_batch_rescan(const ObLogicalOperator *op,
|
||||
const bool allow_normal_scan,
|
||||
const ObIArray<ObExecParamRawExpr*> &rescan_params,
|
||||
bool for_nlj,
|
||||
bool &can_batch_rescan);
|
||||
static int check_can_batch_rescan_compat(const AccessPath &access_path, bool &can_batch_rescan);
|
||||
static int check_can_batch_rescan_compat(ObLogicalOperator *op,
|
||||
const ObIArray<ObExecParamRawExpr*> &rescan_params,
|
||||
bool for_nlj,
|
||||
|
@ -550,6 +550,8 @@ int ObConfigInfoInPC::load_influence_plan_config()
|
||||
0 :
|
||||
(tenant_config->_use_hash_rollup.case_compare("forced") == 0 ? 1 : 2);
|
||||
enable_nlj_spf_use_rich_format_ = tenant_config->_enable_nlj_spf_use_rich_format;
|
||||
enable_distributed_das_scan_ = tenant_config->_enable_distributed_das_scan;
|
||||
enable_das_batch_rescan_flag_ = tenant_config->_enable_das_batch_rescan_flag;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -628,6 +630,12 @@ int ObConfigInfoInPC::serialize_configs(char *buf, int buf_len, int64_t &pos)
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d,", enable_nlj_spf_use_rich_format_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(enable_nlj_spf_use_rich_format_));
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%d,", enable_distributed_das_scan_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(enable_distributed_das_scan_));
|
||||
} else if (OB_FAIL(databuff_printf(buf, buf_len, pos,
|
||||
"%ld,", enable_das_batch_rescan_flag_))) {
|
||||
SQL_PC_LOG(WARN, "failed to databuff_printf", K(ret), K(enable_das_batch_rescan_flag_));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
@ -1041,6 +1041,8 @@ public:
|
||||
min_cluster_version_(0),
|
||||
is_enable_px_fast_reclaim_(false),
|
||||
enable_spf_batch_rescan_(false),
|
||||
enable_distributed_das_scan_(false),
|
||||
enable_das_batch_rescan_flag_(0),
|
||||
enable_var_assign_use_das_(false),
|
||||
enable_das_keep_order_(false),
|
||||
enable_nlj_spf_use_rich_format_(false),
|
||||
@ -1093,6 +1095,8 @@ public:
|
||||
uint64_t min_cluster_version_;
|
||||
bool is_enable_px_fast_reclaim_;
|
||||
bool enable_spf_batch_rescan_;
|
||||
bool enable_distributed_das_scan_;
|
||||
int64_t enable_das_batch_rescan_flag_;
|
||||
bool enable_var_assign_use_das_;
|
||||
bool enable_das_keep_order_;
|
||||
bool enable_nlj_spf_use_rich_format_;
|
||||
|
@ -985,6 +985,10 @@ bool ObOptParamHint::is_param_val_valid(const OptParamType param_type, const ObO
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DAS_BATCH_RESCAN_FLAG: {
|
||||
is_valid = val.is_int() && 0 <= val.get_int();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_TRACE("invalid opt param val", K(param_type), K(val));
|
||||
break;
|
||||
|
@ -202,6 +202,7 @@ struct ObOptParamHint
|
||||
DEF(LOB_ROWSETS_MAX_ROWS,) \
|
||||
DEF(ENABLE_ENUM_SET_SUBSCHEMA,) \
|
||||
DEF(ENABLE_OPTIMIZER_ROWGOAL,) \
|
||||
DEF(DAS_BATCH_RESCAN_FLAG,) \
|
||||
|
||||
DECLARE_ENUM(OptParamType, opt_param, OPT_PARAM_TYPE_DEF, static);
|
||||
|
||||
|
@ -336,12 +336,14 @@ _enable_column_store
|
||||
_enable_compaction_diagnose
|
||||
_enable_compatible_monotonic
|
||||
_enable_convert_real_to_decimal
|
||||
_enable_das_batch_rescan_flag
|
||||
_enable_das_keep_order
|
||||
_enable_dblink_reuse_connection
|
||||
_enable_dbms_job_package
|
||||
_enable_dbms_lob_partial_update
|
||||
_enable_decimal_int_type
|
||||
_enable_defensive_check
|
||||
_enable_distributed_das_scan
|
||||
_enable_drop_and_add_index
|
||||
_enable_easy_keepalive
|
||||
_enable_enhanced_cursor_validation
|
||||
|
Loading…
x
Reference in New Issue
Block a user