optmize the performance of val cmp in query range module

This commit is contained in:
Larry955 2023-07-12 04:48:23 +00:00 committed by ob-robot
parent 5b8a4b982a
commit 73d2e7f520
4 changed files with 67 additions and 18 deletions

View File

@ -1430,7 +1430,7 @@ int ObSelectResolver::resolve_for_update_clause_oracle(const ParseNode &node)
} else if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr is invalid", K(ret), K(expr));
} else if (is_oracle_mode() && expr->get_data_type() == ObURowIDType) {
} else if (is_oracle_mode() && expr->get_expr_type() == T_FUN_SYS_CALC_UROWID) {
ret = OB_ERR_USE_ROWID_FOR_UPDATE;
LOG_WARN("FOR UPDATE OF ROWID is illegal", K(ret), K(*expr));
} else if (OB_UNLIKELY(!expr->is_column_ref_expr())) {

View File

@ -847,8 +847,14 @@ int ObInKeyPart::remove_in_dup_vals()
int val_cnt = get_param_val_cnt();
common::hash::ObHashSet<InParamValsWrapper> distinct_param_val_set;
ObSEArray<InParamValsWrapper, 16> distinct_param_val_arr;
if (OB_FAIL(distinct_param_val_set.create(val_cnt))) {
ObSEArray<obj_cmp_func, MAX_EXTRACT_IN_COLUMN_NUMBER> cmp_funcs;
if (OB_UNLIKELY(param_cnt == 0 || val_cnt == 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get invalid in keypart", K(ret), K(param_cnt), K(val_cnt));
} else if (OB_FAIL(distinct_param_val_set.create(val_cnt))) {
LOG_WARN("failed to create partition macro id set", K(ret));
} else if (OB_FAIL(get_obj_cmp_funcs(cmp_funcs))) {
LOG_WARN("failed to get cmp funcs", K(ret));
}
bool has_dup = false;
for (int64_t i = 0; OB_SUCC(ret) && i < val_cnt; ++i) {
@ -863,6 +869,8 @@ int ObInKeyPart::remove_in_dup_vals()
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(cur_param_vals.cmp_funcs_.assign(cmp_funcs))) {
LOG_WARN("failed to assign cmp func", K(ret));
} else if (OB_HASH_EXIST == (ret = distinct_param_val_set.set_refactored(cur_param_vals, 0))) {
ret = OB_SUCCESS;
has_dup = true;
@ -897,6 +905,28 @@ int ObInKeyPart::remove_in_dup_vals()
return ret;
}
int ObInKeyPart::get_obj_cmp_funcs(ObIArray<obj_cmp_func> &cmp_funcs)
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < in_params_.count(); ++i) {
InParamMeta *cur_param = in_params_.at(i);
obj_cmp_func cmp_op_func = NULL;
if (OB_ISNULL(cur_param) || OB_UNLIKELY(cur_param->vals_.count() == 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get invalid argument", K(ret), K(cur_param), K(i));
} else {
const ObObjTypeClass obj_tc = cur_param->vals_.at(0).get_meta().get_type_class();
if (OB_FAIL(ObObjCmpFuncs::get_cmp_func(obj_tc, obj_tc, CO_EQ, cmp_op_func))) {
LOG_WARN("failed to get cmp func", K(ret), K(obj_tc));
} else {
OB_ASSERT(cmp_op_func != NULL);
ret = cmp_funcs.push_back(cmp_op_func);
}
}
}
return ret;
}
// TODO: can be optimized by hash join algorithm, see ObKeyPart::intersect_two_in_keys, @zhenglailei.zll
int ObKeyPart::union_in_dup_vals(ObKeyPart *other, bool &is_unioned)
{

View File

@ -16,6 +16,7 @@
#include "share/ob_define.h"
#include "lib/objectpool/ob_tc_factory.h"
#include "lib/container/ob_array_serialization.h"
#include "common/object/ob_obj_compare.h"
#include "common/object/ob_object.h"
#include "sql/engine/expr/ob_expr_res_type.h"
#include "lib/hash/ob_placement_hashmap.h"
@ -175,15 +176,34 @@ struct InParamMeta
struct InParamValsWrapper
{
InParamValsWrapper(): param_vals_() { }
int assign(const InParamValsWrapper &other) { return param_vals_.assign(other.param_vals_); }
InParamValsWrapper():
param_vals_(),
cmp_funcs_()
{ }
int assign(const InParamValsWrapper &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(param_vals_.assign(other.param_vals_))) {
SQL_REWRITE_LOG(WARN, "failed to assign param vals", K(ret));
} else if (OB_FAIL(cmp_funcs_.assign(other.cmp_funcs_))) {
SQL_REWRITE_LOG(WARN, "failed to assign cmp funcs", K(ret));
}
return ret;
}
inline bool operator==(const InParamValsWrapper &other) const
{
bool bret = param_vals_.count() == other.param_vals_.count();
for (int64_t i = 0; bret && i < other.param_vals_.count(); ++i) {
if (param_vals_.at(i) != other.param_vals_.at(i)) {
bret = false;
}
int ret = OB_SUCCESS;
int64_t param_cnt = param_vals_.count();
int64_t other_param_cnt = other.param_vals_.count();
int64_t cmp_funcs_cnt = cmp_funcs_.count();
int64_t other_cmp_funcs_cnt = other.cmp_funcs_.count();
bool bret = param_cnt == other_param_cnt && cmp_funcs_cnt == other_cmp_funcs_cnt &&
param_cnt == cmp_funcs_cnt;
ObCompareCtx cmp_ctx(ObMaxType, CS_TYPE_INVALID, true, INVALID_TZ_OFF, default_null_pos());
for (int64_t i = 0; bret && i < param_cnt; ++i) {
obj_cmp_func cmp_op_func = cmp_funcs_.at(i);
OB_ASSERT(NULL != cmp_op_func);
bret = (ObObjCmpFuncs::CR_TRUE == cmp_op_func(param_vals_.at(i), other.param_vals_.at(i), cmp_ctx));
}
return bret;
}
@ -191,21 +211,17 @@ struct InParamValsWrapper
{
return !(*this == other);
}
inline uint64_t hash() const
{
uint64_t hash_code = 0;
for (int64_t i = 0; i < param_vals_.count(); ++i) {
hash_code = param_vals_.at(i).hash(hash_code);
}
return hash_code;
}
inline int hash(uint64_t &hash_code) const
{
int ret = OB_SUCCESS;
hash_code = hash();
for (int64_t i = 0; OB_SUCC(ret) && i < param_vals_.count(); ++i) {
// no need to calculate hash for cmp_funcs_
ret = param_vals_.at(i).hash(hash_code, hash_code);
}
return ret;
}
ObSEArray<ObObj, MAX_EXTRACT_IN_COLUMN_NUMBER> param_vals_;
ObSEArray<obj_cmp_func, MAX_EXTRACT_IN_COLUMN_NUMBER> cmp_funcs_;
TO_STRING_KV(K_(param_vals));
};
@ -246,6 +262,7 @@ struct ObInKeyPart
int get_dup_vals(int64_t offset, const common::ObObj &val, common::ObIArray<int64_t> &dup_val_idx);
int remove_in_dup_vals();
InParamMeta* create_param_meta(common::ObIAllocator &alloc);
int get_obj_cmp_funcs(ObIArray<obj_cmp_func> &cmp_funcs);
uint64_t table_id_;
InParamsArr in_params_;

View File

@ -3786,6 +3786,8 @@ int ObQueryRange::preliminary_extract(const ObRawExpr *node,
LOG_WARN("extract in_op failed", K(ret));
}
}
LOG_TRACE("succeed to extract range from in_expr",
K(use_in_optimization), K(contain_in_), K(is_single_in), K(*out_key_part));
} else if (T_OP_NOT_IN == node->get_expr_type()) {
if (OB_FAIL(pre_extract_not_in_op(b_expr, out_key_part, dtc_params))) {
LOG_WARN("extract in_op failed", K(ret));