Use the cost-based method to select indexes for Oracle inner table

This commit is contained in:
18523270951@163.com
2023-05-25 06:11:20 +00:00
committed by ob-robot
parent e4dfa520cf
commit 81af727eb5
2 changed files with 86 additions and 6 deletions

View File

@ -922,15 +922,25 @@ int ObJoinOrder::get_query_range_info(const uint64_t table_id,
int64_t range_prefix_count = 0;
bool contain_always_false = false;
bool has_exec_param = false;
if (!is_geo_index && OB_FAIL(extract_preliminary_query_range(range_columns,
helper.filters_,
common::ObSEArray<ObRawExpr *, 4> agent_table_filter;
bool is_oracle_inner_index_table = share::is_oracle_mapping_real_virtual_table(index_schema->get_table_id());
if (is_oracle_inner_index_table
&& OB_FAIL(extract_valid_range_expr_for_oracle_agent_table(helper.filters_,
agent_table_filter))) {
LOG_WARN("failed to extract expr", K(ret));
} else if (!is_geo_index && OB_FAIL(extract_preliminary_query_range(range_columns,
is_oracle_inner_index_table
? agent_table_filter
: helper.filters_,
range_info.get_expr_constraints(),
query_range))) {
LOG_WARN("failed to extract query range", K(ret), K(index_id));
} else if (is_geo_index && OB_FAIL(extract_geo_preliminary_query_range(range_columns,
helper.filters_,
geo_columnInfo_map,
query_range))) {
is_oracle_inner_index_table
? agent_table_filter
: helper.filters_,
geo_columnInfo_map,
query_range))) {
LOG_WARN("failed to extract query range", K(ret), K(index_id));
} else if (OB_ISNULL(query_range)) {
ret = OB_ERR_UNEXPECTED;
@ -1072,7 +1082,8 @@ int ObJoinOrder::add_table_by_heuristics(const uint64_t table_id,
ret = OB_INVALID_ARGUMENT;
LOG_WARN("Invalid table id", K(table_id), K(ref_table_id), K(ret));
} else {
if (is_virtual_table(ref_table_id)) {
if (is_virtual_table(ref_table_id)
&& !share::is_oracle_mapping_real_virtual_table(ref_table_id)) {
// check virtual table heuristics
if (OB_FAIL(virtual_table_heuristics(table_id, ref_table_id, index_info_cache,
valid_index_ids, index_to_use))) {
@ -13903,3 +13914,69 @@ int ObJoinOrder::check_can_use_global_stat_instead(const uint64_t ref_table_id,
K(can_use), K(global_part_ids), K(scale_ratio));
return ret;
}
int ObJoinOrder::is_valid_range_expr_for_oracle_agent_table(const ObRawExpr *range_expr,
bool &is_valid)
{
int ret = OB_SUCCESS;
is_valid = false;
bool is_stack_overflow = false;
if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
LOG_WARN("failed to do stack overflow check", K(ret));
} else if (is_stack_overflow) {
ret = OB_SIZE_OVERFLOW;
LOG_WARN("stack overflow", K(ret));
} else if (OB_NOT_NULL(range_expr) && range_expr->is_op_expr()) {
const ObOpRawExpr *expr = static_cast<const ObOpRawExpr *>(range_expr);
if (IS_BASIC_CMP_OP(expr->get_expr_type()) && T_OP_EQ == expr->get_expr_type()) {
is_valid = true;
} else if (T_OP_IS == expr->get_expr_type()
|| T_OP_IN == expr->get_expr_type()) {
is_valid = true;
} else if (T_OP_AND == expr->get_expr_type()) {
is_valid = true;
for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < expr->get_param_count(); ++i) {
if (OB_FAIL(is_valid_range_expr_for_oracle_agent_table(expr->get_param_expr(i),
is_valid))) {
LOG_WARN("failed to check expr", K(ret));
}
}
} else if (T_OP_OR == expr->get_expr_type()) {
is_valid = true;
for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < expr->get_param_count(); ++i) {
if (OB_NOT_NULL(expr->get_param_expr(i))
&& (T_OP_AND == expr->get_param_expr(i)->get_expr_type()
|| T_OP_OR == expr->get_param_expr(i)->get_expr_type()
|| expr->get_param_expr(i)->get_expr_type() != expr->get_param_expr(0)->get_expr_type())) {
is_valid = false;
LOG_TRACE("invalid expr type for oracle agent table range",
K(expr->get_param_expr(i)->get_expr_type()),
K(expr->get_param_expr(0)->get_expr_type()));
} else if (OB_FAIL(is_valid_range_expr_for_oracle_agent_table(expr->get_param_expr(i),
is_valid))) {
LOG_WARN("failed to check expr", K(ret));
}
}
} else {
LOG_TRACE("invalid expr type for oracle agent table range", K(expr->get_expr_type()));
}
}
return ret;
}
int ObJoinOrder::extract_valid_range_expr_for_oracle_agent_table(const ObIArray<ObRawExpr *> &filters,
ObIArray<ObRawExpr *> &new_filters)
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < filters.count(); ++i) {
bool is_valid_expr = false;
if (OB_FAIL(is_valid_range_expr_for_oracle_agent_table(filters.at(i), is_valid_expr))) {
LOG_WARN("failed to check range expr", K(ret));
} else if (!is_valid_expr) {
// skip
} else if (OB_FAIL(new_filters.push_back(filters.at(i)))) {
LOG_WARN("failed to push back filter exprs", K(ret));
}
}
return ret;
}

View File

@ -2454,6 +2454,9 @@ struct NullAwareAntiJoinInfo {
bool &can_use,
ObIArray<int64_t> &global_part_ids,
double &scale_ratio);
int is_valid_range_expr_for_oracle_agent_table(const ObRawExpr *range_expr, bool &is_valid);
int extract_valid_range_expr_for_oracle_agent_table(const common::ObIArray<ObRawExpr *> &filters,
common::ObIArray<ObRawExpr *> &new_filters);
friend class ::test::TestJoinOrder_ob_join_order_param_check_Test;
friend class ::test::TestJoinOrder_ob_join_order_src_Test;
private: