[CP] [CP] add a parameter to control multi version batch rescan scenarios

This commit is contained in:
pe-99y 2025-01-06 15:16:25 +00:00 committed by ob-robot
parent 214dcc5a87
commit 4270b894e9
14 changed files with 213 additions and 47 deletions

View File

@ -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,+∞)",

View File

@ -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,

View File

@ -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;
}

View File

@ -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));

View File

@ -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 */

View File

@ -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) {

View File

@ -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_;
};
}
}

View File

@ -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;

View File

@ -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,

View File

@ -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
}

View File

@ -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_;

View File

@ -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;

View File

@ -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);

View File

@ -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