[CP] [CP] Add limitation for larget set stmts' cost based transformation.

This commit is contained in:
obdev
2022-11-29 12:35:42 +00:00
committed by ob-robot
parent b556f241b3
commit 3f74037737
6 changed files with 47 additions and 26 deletions

View File

@ -294,9 +294,9 @@ int ObOptimizer::get_stmt_max_table_dop(ObDMLStmt &stmt,
table_item->is_fake_cte_table() || table_item->is_fake_cte_table() ||
table_item->is_joined_table()) { table_item->is_joined_table()) {
} else if (table_item->is_temp_table()) { } else if (table_item->is_temp_table()) {
if (OB_FAIL(child_stmts.push_back(table_item->ref_query_))) { if (OB_FAIL(child_stmts.push_back(table_item->ref_query_))) {
LOG_WARN("push back failed", K(ret)); LOG_WARN("push back failed", K(ret));
} }
} else if (table_item->is_generated_table()) { } else if (table_item->is_generated_table()) {
} else { } else {
uint64_t tids[OB_MAX_INDEX_PER_TABLE + 1]; uint64_t tids[OB_MAX_INDEX_PER_TABLE + 1];

View File

@ -165,7 +165,8 @@ int ObTransformRule::transform_stmt_recursively(common::ObIArray<ObParentDMLStmt
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
bool is_stack_overflow = false; bool is_stack_overflow = false;
if (OB_ISNULL(stmt)) { int64_t size = 0;
if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) {
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
LOG_WARN("stmt is NULL", K(ret)); LOG_WARN("stmt is NULL", K(ret));
} else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) { } else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
@ -173,7 +174,10 @@ int ObTransformRule::transform_stmt_recursively(common::ObIArray<ObParentDMLStmt
} else if (is_stack_overflow) { } else if (is_stack_overflow) {
ret = OB_SIZE_OVERFLOW; ret = OB_SIZE_OVERFLOW;
LOG_WARN("too deep recursive", K(current_level), K(is_stack_overflow), K(ret)); LOG_WARN("too deep recursive", K(current_level), K(is_stack_overflow), K(ret));
} else if (is_large_stmt(*stmt) && } else if (stmt->is_select_stmt() &&
OB_FAIL(static_cast<const ObSelectStmt *>(stmt)->get_set_stmt_size(size))) {
LOG_WARN("failed to get set stm size", K(ret));
} else if (size > common::OB_MAX_SET_STMT_SIZE &&
!(transformer_type_ == PRE_PROCESS || !(transformer_type_ == PRE_PROCESS ||
transformer_type_ == POST_PROCESS)) { transformer_type_ == POST_PROCESS)) {
// skip transformation for large stmt // skip transformation for large stmt
@ -270,6 +274,8 @@ int ObTransformRule::accept_transform(common::ObIArray<ObParentDMLStmt> &parent_
LOG_WARN("context is null", K(ret), K(ctx_), K(stmt), K(trans_stmt), K(top_stmt)); LOG_WARN("context is null", K(ret), K(ctx_), K(stmt), K(trans_stmt), K(top_stmt));
} else if (force_accept) { } else if (force_accept) {
trans_happened = true; trans_happened = true;
} else if (ctx_->is_set_stmt_oversize_) {
LOG_TRACE("not accept transform because large set stmt", K(ctx_->is_set_stmt_oversize_));
} else if (OB_FAIL(evaluate_cost(parent_stmts, trans_stmt, true, } else if (OB_FAIL(evaluate_cost(parent_stmts, trans_stmt, true,
trans_stmt_cost, is_expected, check_ctx))) { trans_stmt_cost, is_expected, check_ctx))) {
LOG_WARN("failed to evaluate cost for the transformed stmt", K(ret)); LOG_WARN("failed to evaluate cost for the transformed stmt", K(ret));
@ -281,11 +287,10 @@ int ObTransformRule::accept_transform(common::ObIArray<ObParentDMLStmt> &parent_
} else { } else {
trans_happened = trans_stmt_cost < stmt_cost_; trans_happened = trans_stmt_cost < stmt_cost_;
} }
if (OB_FAIL(ret)) { if (OB_FAIL(ret)) {
} else if (!trans_happened) { } else if (!trans_happened) {
LOG_TRACE("reject transform because the cost is increased or the query plan is unexpected", LOG_TRACE("reject transform because the cost is increased or the query plan is unexpected",
K_(stmt_cost), K(trans_stmt_cost), K(is_expected)); K_(ctx_->is_set_stmt_oversize), K_(stmt_cost), K(trans_stmt_cost), K(is_expected));
} else if (OB_FAIL(adjust_transformed_stmt(parent_stmts, trans_stmt, tmp1, tmp2))) { } else if (OB_FAIL(adjust_transformed_stmt(parent_stmts, trans_stmt, tmp1, tmp2))) {
LOG_WARN("failed to adjust transformed stmt", K(ret)); LOG_WARN("failed to adjust transformed stmt", K(ret));
} else if (force_accept) { } else if (force_accept) {
@ -737,20 +742,6 @@ bool ObTransformRule::is_view_stmt(const ObIArray<ObParentDMLStmt> &parents, con
return bret; return bret;
} }
bool ObTransformRule::is_large_stmt(const ObDMLStmt &stmt)
{
bool bret = false;
int ret = OB_SUCCESS;
int64_t size = 0;
if (stmt.is_select_stmt()) {
if (OB_FAIL(static_cast<const ObSelectStmt&>(stmt).get_set_stmt_size(size))) {
LOG_WARN("failed to get set stm size", K(ret));
} else if (size > common::OB_MAX_SET_STMT_SIZE) {
bret = true;
}
}
return bret;
}
int ObTryTransHelper::fill_helper(const ObQueryCtx *query_ctx) int ObTryTransHelper::fill_helper(const ObQueryCtx *query_ctx)
{ {

View File

@ -53,6 +53,7 @@ struct ObTransformerCtx
expr_constraints_(), expr_constraints_(),
plan_const_param_constraints_(), plan_const_param_constraints_(),
equal_param_constraints_(), equal_param_constraints_(),
is_set_stmt_oversize_(false),
happened_cost_based_trans_(0), happened_cost_based_trans_(0),
equal_sets_(), equal_sets_(),
ignore_semi_infos_(), ignore_semi_infos_(),
@ -108,6 +109,7 @@ struct ObTransformerCtx
ObSEArray<ObExprConstraint, 4, common::ModulePageAllocator, true> expr_constraints_; ObSEArray<ObExprConstraint, 4, common::ModulePageAllocator, true> expr_constraints_;
ObSEArray<ObPCConstParamInfo, 4, common::ModulePageAllocator, true> plan_const_param_constraints_; ObSEArray<ObPCConstParamInfo, 4, common::ModulePageAllocator, true> plan_const_param_constraints_;
ObSEArray<ObPCParamEqualInfo, 4, common::ModulePageAllocator, true> equal_param_constraints_; ObSEArray<ObPCParamEqualInfo, 4, common::ModulePageAllocator, true> equal_param_constraints_;
bool is_set_stmt_oversize_;
// record cost based transformers // record cost based transformers
uint64_t happened_cost_based_trans_; uint64_t happened_cost_based_trans_;
EqualSets equal_sets_; EqualSets equal_sets_;
@ -415,8 +417,6 @@ private:
bool is_view_stmt(const ObIArray<ObParentDMLStmt> &parents, bool is_view_stmt(const ObIArray<ObParentDMLStmt> &parents,
const ObDMLStmt &stmt); const ObDMLStmt &stmt);
bool is_large_stmt(const ObDMLStmt &stmt);
bool skip_move_trans_loc() const bool skip_move_trans_loc() const
{ {
return TEMP_TABLE_OPTIMIZATION == transformer_type_ // move trans loc in transform rule return TEMP_TABLE_OPTIMIZATION == transformer_type_ // move trans loc in transform rule
@ -431,7 +431,6 @@ private:
|| PREDICATE_MOVE_AROUND == transformer_type_; || PREDICATE_MOVE_AROUND == transformer_type_;
} }
DISALLOW_COPY_AND_ASSIGN(ObTransformRule); DISALLOW_COPY_AND_ASSIGN(ObTransformRule);
protected: protected:

View File

@ -63,6 +63,8 @@ int ObTransformerImpl::transform(ObDMLStmt *&stmt)
if (OB_ISNULL(stmt)) { if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret)); LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(SMART_CALL(get_stmt_trans_info(stmt)))) {
LOG_WARN("get_stmt_trans_info failed", K(ret));
} else if (OB_FAIL(do_transform_pre_precessing(stmt))) { } else if (OB_FAIL(do_transform_pre_precessing(stmt))) {
LOG_WARN("failed to do transform pre_precessing", K(ret)); LOG_WARN("failed to do transform pre_precessing", K(ret));
} else if (OB_FAIL(stmt->formalize_stmt_expr_reference())) { } else if (OB_FAIL(stmt->formalize_stmt_expr_reference())) {
@ -81,6 +83,34 @@ int ObTransformerImpl::transform(ObDMLStmt *&stmt)
return ret; return ret;
} }
int ObTransformerImpl::get_stmt_trans_info(ObDMLStmt *stmt)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt is null", K(ret));
} else if (stmt->is_select_stmt()) {
int64_t size = 0;
if (OB_FAIL(static_cast<ObSelectStmt *>(stmt)->get_set_stmt_size(size))) {
LOG_WARN("get set stmt size failed", K(ret));
} else if (size > ObTransformerImpl::MAX_SET_STMT_SIZE_OF_COSTED_BASED_RELUES) {
ctx_->is_set_stmt_oversize_ = true;
}
}
if (OB_SUCC(ret) && !ctx_->is_set_stmt_oversize_) {
ObSEArray<ObSelectStmt*, 4> child_stmts;
if (OB_FAIL(stmt->get_child_stmts(child_stmts))) {
LOG_WARN("failed to get child stmts", K(ret));
}
for (int64_t i = 0; OB_SUCC(ret) && !ctx_->is_set_stmt_oversize_&& i < child_stmts.count(); i++) {
if (OB_FAIL(SMART_CALL(get_stmt_trans_info(child_stmts.at(i))))) {
LOG_WARN("get_stmt_trans_info failed", K(ret));
}
}
}
return ret;
}
int ObTransformerImpl::do_transform(ObDMLStmt *&stmt) int ObTransformerImpl::do_transform(ObDMLStmt *&stmt)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;

View File

@ -50,6 +50,7 @@ class ObTransformerImpl
{ {
static const int64_t DEFAULT_ITERATION_COUNT = 10; static const int64_t DEFAULT_ITERATION_COUNT = 10;
static const int64_t MAX_RULE_COUNT = 64; static const int64_t MAX_RULE_COUNT = 64;
static const uint64_t MAX_SET_STMT_SIZE_OF_COSTED_BASED_RELUES = 5;
public: public:
ObTransformerImpl(ObTransformerCtx *ctx) ObTransformerImpl(ObTransformerCtx *ctx)
: ctx_(ctx), : ctx_(ctx),
@ -146,7 +147,7 @@ public:
private: private:
int collect_trans_stat(const ObTransformRule &rule); int collect_trans_stat(const ObTransformRule &rule);
int get_stmt_trans_info(ObDMLStmt *stmt);
void print_trans_stat(); void print_trans_stat();
int finalize_exec_params(ObDMLStmt *stmt); int finalize_exec_params(ObDMLStmt *stmt);