[CP] In a multi-level join scenario, batch_rescan cannot be performed when the right branch of NLJ appear to be non-NLJ

This commit is contained in:
yishenglanlingzui 2023-10-10 13:47:36 +00:00 committed by ob-robot
parent a36e27e80b
commit d06948658f
2 changed files with 35 additions and 19 deletions

View File

@ -1198,20 +1198,21 @@ int ObLogJoin::set_use_batch(ObLogicalOperator* root)
}
}
} else if (log_op_def::LOG_JOIN == root->get_type()) {
ObLogJoin *nlj = NULL;
ObLogicalOperator *child = NULL;
if (OB_ISNULL(nlj = static_cast<ObLogJoin *>(root))
|| OB_ISNULL(child = nlj->get_child(0))) {
ObLogJoin *join = NULL;
ObLogicalOperator *left_child = NULL;
ObLogicalOperator *rigtht_child = NULL;
if (OB_ISNULL(join = static_cast<ObLogJoin *>(root))
|| OB_ISNULL(left_child = join->get_child(0))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid input", K(ret));
} else if (OB_FAIL(SMART_CALL(set_use_batch(child)))) {
} else if (OB_FAIL(SMART_CALL(set_use_batch(left_child)))) {
LOG_WARN("failed to check use batch nlj", K(ret));
} else if (!nlj->can_use_batch_nlj()) {
} else if (!join->can_use_batch_nlj()) {
// do nothing
} else if (OB_ISNULL(child = nlj->get_child(1))) {
} else if (OB_ISNULL(rigtht_child = join->get_child(1))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid child", K(ret));
} else if (OB_FAIL(SMART_CALL(set_use_batch(child)))) {
} else if (OB_FAIL(SMART_CALL(set_use_batch(rigtht_child)))) {
LOG_WARN("failed to check use batch nlj", K(ret));
}
} else { /*do nothing*/ }
@ -1249,7 +1250,7 @@ int ObLogJoin::check_and_set_use_batch()
LOG_WARN("failed to check contains limit", K(ret));
} else if (contains_limit) {
can_use_batch_nlj_ = false;
} else if (OB_FAIL(check_if_disable_batch(get_child(1)))) {
} else if (OB_FAIL(check_if_disable_batch(get_child(1), can_use_batch_nlj_))) {
LOG_WARN("failed to check if disable batch", K(ret));
}
}
@ -1262,13 +1263,13 @@ int ObLogJoin::check_and_set_use_batch()
return ret;
}
int ObLogJoin::check_if_disable_batch(ObLogicalOperator* root)
int ObLogJoin::check_if_disable_batch(ObLogicalOperator* root, bool &can_use_batch_nlj)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(root)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret));
} else if (!can_use_batch_nlj_) {
} else if (!can_use_batch_nlj) {
// do nothing
} else if (root->is_table_scan()) {
ObLogTableScan *ts = NULL;
@ -1282,7 +1283,7 @@ int ObLogJoin::check_if_disable_batch(ObLogicalOperator* root)
} else if (ts->has_index_scan_filter() && ts->get_index_back() && ts->get_is_index_global()) {
// For the global index lookup, if there is a pushdown filter when scanning the index,
// batch cannot be used.
can_use_batch_nlj_ = false;
can_use_batch_nlj = false;
} else {
SMART_VAR(ObTablePartitionInfo, tmp_info) {
ObTablePartitionInfo *tmp_info_ptr = &tmp_info;
@ -1293,26 +1294,41 @@ int ObLogJoin::check_if_disable_batch(ObLogicalOperator* root)
tmp_info.get_table_location().get_has_dynamic_exec_param()) {
// dynamic partition pruning, no need to check
} else if (10 < info->get_phy_tbl_location_info().get_phy_part_loc_info_list().count()) {
can_use_batch_nlj_ = false;
can_use_batch_nlj = false;
}
}
}
}
} else if (log_op_def::LOG_SUBPLAN_SCAN == root->get_type()) {
if (OB_FAIL(SMART_CALL(check_if_disable_batch(root->get_child(0))))) {
} else if (1 == root->get_num_of_child()) {
if (OB_FAIL(SMART_CALL(check_if_disable_batch(root->get_child(0), can_use_batch_nlj)))) {
LOG_WARN("failed to check if disable batch", K(ret));
}
} else if (log_op_def::LOG_SET == root->get_type()) {
for (int64_t i = 0; OB_SUCC(ret) && can_use_batch_nlj_ && i < root->get_num_of_child(); ++i) {
for (int64_t i = 0; OB_SUCC(ret) && can_use_batch_nlj && i < root->get_num_of_child(); ++i) {
ObLogicalOperator *child = root->get_child(i);
if (OB_ISNULL(child)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid child", K(ret));
} else if (OB_FAIL(SMART_CALL(check_if_disable_batch(child)))) {
} else if (OB_FAIL(SMART_CALL(check_if_disable_batch(child, can_use_batch_nlj)))) {
LOG_WARN("failed to check if disable batch", K(ret));
}
}
} else { /* do nothing */ }
} else if (log_op_def::LOG_JOIN == root->get_type()) {
ObLogJoin *join = NULL;
if (OB_ISNULL(join = static_cast<ObLogJoin *>(root))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid input", K(ret));
} else if (!join->can_use_batch_nlj()) {
can_use_batch_nlj = false;
LOG_TRACE("child join not support batch_nlj", K(root->get_name()));
} else if (OB_FAIL(SMART_CALL(check_if_disable_batch(root->get_child(0), can_use_batch_nlj)))) {
LOG_WARN("failed to check use batch nlj", K(ret));
} else if (OB_FAIL(SMART_CALL(check_if_disable_batch(root->get_child(1), can_use_batch_nlj)))) {
LOG_WARN("failed to check use batch nlj for right op", K(ret));
}
} else {
can_use_batch_nlj = false;
}
return ret;
}

View File

@ -153,7 +153,7 @@ namespace sql
inline bool can_use_batch_nlj() const { return can_use_batch_nlj_; }
void set_can_use_batch_nlj(bool can_use) { can_use_batch_nlj_ = can_use; }
int check_and_set_use_batch();
int check_if_disable_batch(ObLogicalOperator* root);
int check_if_disable_batch(ObLogicalOperator* root, bool &can_use_batch_nlj);
void set_join_path(JoinPath *path) { join_path_ = path; }
JoinPath *get_join_path() { return join_path_; }
bool is_my_exec_expr(const ObRawExpr *expr);