[FEAT MERGE] skip scan feature and performance optimization

This commit is contained in:
obdev
2023-01-04 09:08:22 +00:00
committed by ob-robot
parent ad415b4359
commit 07b1224a51
119 changed files with 6176 additions and 2010 deletions

View File

@ -1171,7 +1171,10 @@ int ObStmtHint::merge_other_opt_hint(const ObIArray<ObHint*> &hints,
switch (hint->get_hint_type()) {
case T_INDEX_HINT:
case T_NO_INDEX_HINT:
case T_FULL_HINT: {
case T_FULL_HINT:
case T_INDEX_SS_HINT:
case T_INDEX_SS_ASC_HINT:
case T_INDEX_SS_DESC_HINT: {
hint_type = T_INDEX_HINT;
break;
}
@ -1797,6 +1800,34 @@ int ObLogPlanHint::check_use_das(uint64_t table_id, bool &force_das, bool &force
return ret;
}
int ObLogPlanHint::check_use_skip_scan(uint64_t table_id,
uint64_t index_id,
bool &force_skip_scan,
bool &force_no_skip_scan) const
{
int ret = OB_SUCCESS;
force_skip_scan = false;
force_no_skip_scan = false;
const LogTableHint *log_table_hint = get_log_table_hint(table_id);
int64_t pos = OB_INVALID_INDEX;
if (NULL != log_table_hint &&
ObOptimizerUtil::find_item(log_table_hint->index_list_, index_id, &pos)) {
const ObIndexHint *hint = NULL;
if (OB_UNLIKELY(pos >= log_table_hint->index_hints_.count() || pos < 0)
|| OB_ISNULL(hint = log_table_hint->index_hints_.at(pos))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected pos", K(ret), K(pos), K(log_table_hint->index_hints_.count()), K(hint));
} else {
force_skip_scan = hint->use_skip_scan();
force_no_skip_scan = !force_skip_scan && hint->is_use_index_hint();
}
}
if (OB_SUCC(ret) && !force_skip_scan && !force_no_skip_scan && is_outline_data_) {
force_no_skip_scan = true;
}
return ret;
}
int ObLogPlanHint::check_use_join_filter(uint64_t filter_table_id,
const ObRelIds &left_tables,
bool part_join_filter,
@ -2183,7 +2214,6 @@ int LogTableHint::assign(const LogTableHint &other)
{
int ret = OB_SUCCESS;
table_ = other.table_;
index_type_ = other.index_type_;
parallel_hint_ = other.parallel_hint_;
use_das_hint_ = other.use_das_hint_;
if (OB_FAIL(index_list_.assign(other.index_list_))) {
@ -2223,9 +2253,10 @@ int LogTableHint::init_index_hints(ObSqlSchemaGuard &schema_guard)
} else {
LOG_TRACE("get readable index", K(table_index_count));
const share::schema::ObTableSchema *index_schema = NULL;
ObItemType index_hint_type = T_INVALID;
ObSEArray<uint64_t, 4> index_list;
ObSEArray<const ObIndexHint*, 4> hints;
ObSEArray<uint64_t, 4> no_index_list;
ObSEArray<const ObIndexHint*, 4> index_hints;
ObSEArray<const ObIndexHint*, 4> no_index_hints;
for (int64_t i = -1; OB_SUCC(ret) && i < table_index_count; ++i) {
uint64_t index_id = -1 == i ? table_->ref_id_ : tids[i];
ObString index_name;
@ -2244,54 +2275,63 @@ int LogTableHint::init_index_hints(ObSqlSchemaGuard &schema_guard)
}
if (OB_SUCC(ret) && (!index_name.empty())) {
int64_t hint_pos = OB_INVALID_INDEX;
int64_t no_index_hint_pos = OB_INVALID_INDEX;
int64_t index_hint_pos = OB_INVALID_INDEX;
int64_t index_ss_hint_pos = OB_INVALID_INDEX;
const uint64_t N = index_hints_.count();
const ObIndexHint *index_hint = NULL;
bool use_index = false;
bool no_use_index = false;
for (int64_t hint_i = 0; OB_SUCC(ret) && hint_i < N; ++hint_i) {
if (OB_ISNULL(index_hint = index_hints_.at(hint_i)) ||
OB_UNLIKELY(!index_hint->is_access_path_hint())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null index hint", K(ret), K(index_hint));
} else if ((is_primary_key && T_FULL_HINT == index_hint->get_hint_type())
|| 0 == index_hint->get_index_name().case_compare(index_name)) {
hint_pos = hint_i;
use_index |= T_INDEX_HINT == index_hint->get_hint_type()
|| T_FULL_HINT == index_hint->get_hint_type();
no_use_index |= T_NO_INDEX_HINT == index_hint->get_hint_type();
} else if (is_primary_key && T_FULL_HINT == index_hint->get_hint_type()) {
index_hint_pos = hint_i;
} else if (0 != index_hint->get_index_name().case_compare(index_name)) {
/* do nothing */
} else if (T_NO_INDEX_HINT == index_hint->get_hint_type()) {
no_index_hint_pos = hint_i;
} else if (T_INDEX_SS_HINT == index_hint->get_hint_type()) {
index_ss_hint_pos = hint_i;
} else {
index_hint_pos = hint_i;
}
}
if (hint_pos >= 0 && hint_pos < N) {
if (use_index && no_use_index) {
/* conflict full/index and no_index hint*/
} else if (no_use_index && T_INDEX_HINT == index_hint_type) {
/* get vaild index hint, ignore this no_index hint*/
} else {
if (use_index && T_NO_INDEX_HINT == index_hint_type) {
hints.reuse();
index_list.reuse();
}
index_hint_type = use_index ? T_INDEX_HINT : T_NO_INDEX_HINT;
if (OB_FAIL(index_list.push_back(index_id))) {
LOG_WARN("fail to push back", K(ret), K(index_id));
} else if (OB_FAIL(hints.push_back(index_hints_.at(hint_pos)))) {
LOG_WARN("fail to push back", K(ret), K(hint_pos));
}
if (OB_FAIL(ret)) {
} else if (OB_INVALID_INDEX != no_index_hint_pos
&& (OB_INVALID_INDEX != index_ss_hint_pos
|| OB_INVALID_INDEX != index_hint_pos)) {
/* conflict full/index/index_ss and no_index hint*/
} else if (OB_INVALID_INDEX != no_index_hint_pos) {
if (OB_FAIL(no_index_list.push_back(index_id))) {
LOG_WARN("fail to push back", K(ret), K(index_id));
} else if (OB_FAIL(no_index_hints.push_back(index_hints_.at(no_index_hint_pos)))) {
LOG_WARN("fail to push back", K(ret), K(no_index_hint_pos));
}
} else if (OB_INVALID_INDEX != index_ss_hint_pos
|| OB_INVALID_INDEX != index_hint_pos) {
int64_t hint_pos = OB_INVALID_INDEX != index_ss_hint_pos
? index_ss_hint_pos : index_hint_pos;
if (OB_FAIL(index_list.push_back(index_id))) {
LOG_WARN("fail to push back", K(ret), K(index_id));
} else if (OB_FAIL(index_hints.push_back(index_hints_.at(hint_pos)))) {
LOG_WARN("fail to push back", K(ret), K(hint_pos));
}
}
}
}
if (OB_FAIL(ret)) {
} else if (OB_UNLIKELY(index_list.count() != hints.count())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected log index hint", K(ret), K(index_list), K(hints));
} else if (OB_FAIL(index_list_.assign(index_list))) {
LOG_WARN("failed to assign array", K(ret));
} else if (OB_FAIL(index_hints_.assign(hints))) {
LOG_WARN("failed to assign array", K(ret));
} else {
index_type_ = index_hint_type;
if (OB_SUCC(ret)) {
if (!index_list.empty()) {
if (OB_FAIL(index_list_.assign(index_list))) {
LOG_WARN("failed to assign array", K(ret));
} else if (OB_FAIL(index_hints_.assign(index_hints))) {
LOG_WARN("failed to assign array", K(ret));
}
} else if (OB_FAIL(index_list_.assign(no_index_list))) {
LOG_WARN("failed to assign array", K(ret));
} else if (OB_FAIL(index_hints_.assign(no_index_hints))) {
LOG_WARN("failed to assign array", K(ret));
}
}
}
return ret;
@ -2367,5 +2407,31 @@ int LogTableHint::add_join_filter_hint(const ObDMLStmt &stmt,
return ret;
}
int LogTableHint::allowed_skip_scan(const uint64_t index_id, bool &allowed) const
{
int ret = OB_SUCCESS;
allowed = false;
if (!is_use_index_hint()) {
/* do nothing */
} else if (OB_UNLIKELY(index_list_.count() != index_hints_.count())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected count", K(ret), K(index_list_.count()), K(index_hints_.count()));
} else {
bool find = false;
for (int64_t i = 0; OB_SUCC(ret) && !find && i < index_list_.count(); ++i) {
if (index_list_.at(i) != index_id) {
/* do nothing */
} else if (OB_ISNULL(index_hints_.at(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), K(i), K(index_hints_));
} else {
allowed = T_INDEX_SS_HINT == index_hints_.at(i)->get_hint_type();
find = true;
}
}
}
return ret;
}
}//end of namespace sql
}//end of namespace oceanbase