From abef1a89a4152f0be99e16d3dde7d55579816e04 Mon Sep 17 00:00:00 2001 From: obdev Date: Fri, 22 Dec 2023 15:42:36 +0000 Subject: [PATCH] Tracepoint: Add trace point to test NLJ and SPF batch rescan --- deps/oblib/src/lib/utility/ob_tracepoint.h | 2 ++ src/sql/engine/basic/ob_group_join_buffer.cpp | 3 ++ .../engine/join/ob_nested_loop_join_op.cpp | 18 +++++++++-- .../engine/subquery/ob_subplan_filter_op.cpp | 4 ++- src/sql/optimizer/ob_join_order.cpp | 32 ++++++++++++++++++- 5 files changed, 55 insertions(+), 4 deletions(-) diff --git a/deps/oblib/src/lib/utility/ob_tracepoint.h b/deps/oblib/src/lib/utility/ob_tracepoint.h index 92bc49cf2..b3dc6f9ca 100644 --- a/deps/oblib/src/lib/utility/ob_tracepoint.h +++ b/deps/oblib/src/lib/utility/ob_tracepoint.h @@ -589,6 +589,7 @@ class EventTable EN_DAS_SIMULATE_DUMP_WRITE_BUFFER = 308, EN_DAS_SIMULATE_AGG_TASK_BUFF_LIMIT = 309, EN_DAS_ALL_PARALLEL_TASK_MEM_LIMIT = 310, + EN_DAS_SIMULATE_GROUP_SIZE = 311, EN_REPLAY_STORAGE_SCHEMA_FAILURE = 351, EN_SKIP_GET_STORAGE_SCHEMA = 352, @@ -636,6 +637,7 @@ class EventTable EN_EXPLAIN_GENERATE_PLAN_WITH_OUTLINE = 551, EN_ENABLE_AUTO_DOP_FORCE_PARALLEL_PLAN = 552, EN_GENERATE_PLAN_WITH_RECONSTRUCT_SQL = 553, + EN_GENERATE_PLAN_WITH_NLJ = 554, // 600-700 For PX use EN_PX_SQC_EXECUTE_FAILED = 600, diff --git a/src/sql/engine/basic/ob_group_join_buffer.cpp b/src/sql/engine/basic/ob_group_join_buffer.cpp index ba8e9df5c..11424c53b 100644 --- a/src/sql/engine/basic/ob_group_join_buffer.cpp +++ b/src/sql/engine/basic/ob_group_join_buffer.cpp @@ -141,6 +141,9 @@ int ObGroupJoinBufffer::init(ObOperator *op, } else if (OB_UNLIKELY(op->get_child_cnt() < 2)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("op should have at least 2 children", KR(ret), K(op->get_child_cnt())); + } else if (max_group_size < group_scan_size) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("max group size is less than group scan size", K(max_group_size), K(group_scan_size)); } else { op_ = op; spec_ = &op_->get_spec(); diff --git a/src/sql/engine/join/ob_nested_loop_join_op.cpp b/src/sql/engine/join/ob_nested_loop_join_op.cpp index 3061aac40..d33c996fe 100644 --- a/src/sql/engine/join/ob_nested_loop_join_op.cpp +++ b/src/sql/engine/join/ob_nested_loop_join_op.cpp @@ -66,9 +66,23 @@ int ObNestedLoopJoinOp::inner_open() } else if (OB_FAIL(ObBasicNestedLoopJoinOp::inner_open())) { LOG_WARN("failed to open in base class", K(ret)); } + int64_t simulate_group_size = - EVENT_CALL(EventTable::EN_DAS_SIMULATE_GROUP_SIZE); + int64_t group_size = 0; + if (simulate_group_size > 0) { + max_group_size_ = simulate_group_size; + group_size = simulate_group_size; + LOG_TRACE("simulate group size is", K(simulate_group_size)); + } else { + group_size = MY_SPEC.group_size_; + } if (OB_SUCC(ret) && is_vectorized()) { if (MY_SPEC.group_rescan_) { - max_group_size_ = OB_MAX_BULK_JOIN_ROWS + MY_SPEC.plan_->get_batch_size(); + if (simulate_group_size > 0) { + max_group_size_ = simulate_group_size + MY_SPEC.plan_->get_batch_size(); + } else { + max_group_size_ = OB_MAX_BULK_JOIN_ROWS + MY_SPEC.plan_->get_batch_size(); + } + LOG_TRACE("max group size of NLJ is", K(max_group_size_), K(MY_SPEC.plan_->get_batch_size())); } if (OB_ISNULL(batch_mem_ctx_)) { ObSQLSessionInfo *session = ctx_.get_my_session(); @@ -114,7 +128,7 @@ int ObNestedLoopJoinOp::inner_open() if (OB_SUCC(ret) && MY_SPEC.group_rescan_) { if (OB_FAIL(group_join_buffer_.init(this, max_group_size_, - MY_SPEC.group_size_, + group_size, &MY_SPEC.rescan_params_, &MY_SPEC.left_rescan_params_, &MY_SPEC.right_rescan_params_))) { diff --git a/src/sql/engine/subquery/ob_subplan_filter_op.cpp b/src/sql/engine/subquery/ob_subplan_filter_op.cpp index 6670e3e64..40b1e18eb 100644 --- a/src/sql/engine/subquery/ob_subplan_filter_op.cpp +++ b/src/sql/engine/subquery/ob_subplan_filter_op.cpp @@ -686,7 +686,9 @@ int ObSubPlanFilterOp::inner_open() //BATCH SUBPLAN FILTER { if (OB_SUCC(ret) && MY_SPEC.enable_das_group_rescan_) { - max_group_size_ = OB_MAX_BULK_JOIN_ROWS; + int64_t simulate_group_size = - EVENT_CALL(EventTable::EN_DAS_SIMULATE_GROUP_SIZE); + max_group_size_ = simulate_group_size > 0 ? simulate_group_size: OB_MAX_BULK_JOIN_ROWS; + LOG_TRACE("max group size of SPF is", K(max_group_size_)); if(OB_FAIL(alloc_das_batch_params(max_group_size_+MY_SPEC.max_batch_size_))) { LOG_WARN("Fail to alloc das batch params.", K(ret)); } diff --git a/src/sql/optimizer/ob_join_order.cpp b/src/sql/optimizer/ob_join_order.cpp index e7051d342..f6ba41f7a 100644 --- a/src/sql/optimizer/ob_join_order.cpp +++ b/src/sql/optimizer/ob_join_order.cpp @@ -1547,8 +1547,10 @@ int ObJoinOrder::will_use_das(const uint64_t table_id, create_basic_path = false; } else if ((helper.is_inner_path_ || get_tables().is_subset(get_plan()->get_subq_pdfilter_tset())) && !is_virtual_table(ref_id)) { + bool force_use_nlj = false; + force_use_nlj = (OB_SUCCESS != (OB_E(EventTable::EN_GENERATE_PLAN_WITH_NLJ) OB_SUCCESS)); create_das_path = true; - create_basic_path = true; + create_basic_path = force_use_nlj ? false : true; } else if (index_info_entry->is_index_global() && ObGlobalHint::UNSET_PARALLEL == explicit_dop) { // for global index use auto dop, create das path and basic path, after get auto dop result, prune unnecessary path create_das_path = true; @@ -11277,6 +11279,14 @@ int ObJoinOrder::get_valid_path_info(const ObJoinOrder &left_tree, path_info.local_methods_ &= ~MERGE_JOIN; OPT_TRACE("right semi/anti join can not use nested loop/merge join"); } + if (OB_SUCC(ret)) { + bool force_use_nlj = false; + force_use_nlj = (OB_SUCCESS != (OB_E(EventTable::EN_GENERATE_PLAN_WITH_NLJ) OB_SUCCESS)); + if (force_use_nlj) { + path_info.local_methods_ &= ~MERGE_JOIN; + path_info.local_methods_ |= NESTED_LOOP_JOIN; + } + } //check batch update join type if (OB_SUCC(ret) && get_plan()->get_optimizer_context().is_batched_multi_stmt()) { // left_tree is the generated table of batch params and right tree is other path -> NLJ @@ -12132,6 +12142,26 @@ int ObJoinOrder::create_and_add_nl_path(const Path *left_path, LOG_TRACE("succeed to create a nested loop join path", K(join_type), K(join_dist_algo), K(need_mat), K(on_conditions), K(where_conditions)); } + // Trace point to force use NLJ as possible + if (OB_SUCC(ret)) { + bool force_use_nlj = false; + force_use_nlj = (OB_SUCCESS != (OB_E(EventTable::EN_GENERATE_PLAN_WITH_NLJ) OB_SUCCESS)); + if (force_use_nlj && !join_path->contain_normal_nl_) { + LOG_TRACE("trigger trace point to generate nest-loop join"); + if (OB_FAIL(interesting_paths_.push_back(join_path))) { + LOG_WARN("failed to push back nlj path"); + } else { + for (int64_t i = interesting_paths_.count() - 1; OB_SUCC(ret) && i >= 0; --i) { + JoinPath *join_path = reinterpret_cast(interesting_paths_.at(i)); + if (join_path->join_algo_ != NESTED_LOOP_JOIN) { + if (OB_FAIL(interesting_paths_.remove(i))) { + LOG_WARN("failed to remove dominated plans", K(i), K(ret)); + } + } + } + } + } + } } return ret; }