optmize the performance of val cmp in query range module
This commit is contained in:
parent
5b8a4b982a
commit
73d2e7f520
@ -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())) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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_;
|
||||
|
@ -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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user