[CP] 修复不稳定索引剪枝规则裁剪不完全的问题
This commit is contained in:
parent
4d81ba0b8c
commit
4481ef728c
@ -864,9 +864,6 @@ int ObOptimizerTraceImpl::append(const ObSkylineDim &dim)
|
||||
case ObSkylineDim::INDEX_BACK: {
|
||||
const ObIndexBackDim &index_dim = static_cast<const ObIndexBackDim &>(dim);
|
||||
append("[index back dim] need index back:", index_dim.need_index_back_);
|
||||
append(", has interesting order:", index_dim.has_interesting_order_);
|
||||
append(", can extract range:", index_dim.can_extract_range_);
|
||||
append(", filter columns:", common::ObArrayWrap<uint64_t>(index_dim.filter_column_ids_, index_dim.filter_column_cnt_));
|
||||
break;
|
||||
}
|
||||
case ObSkylineDim::INTERESTING_ORDER: {
|
||||
|
@ -2442,7 +2442,8 @@ int ObJoinOrder::cal_dimension_info(const uint64_t table_id, //alias table id
|
||||
const ObDMLStmt *stmt,
|
||||
ObIndexSkylineDim &index_dim,
|
||||
const ObIndexInfoCache &index_info_cache,
|
||||
ObIArray<ObRawExpr *> &restrict_infos)
|
||||
ObIArray<ObRawExpr *> &restrict_infos,
|
||||
bool ignore_index_back_dim)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSqlSchemaGuard *guard = NULL;
|
||||
@ -2459,7 +2460,7 @@ int ObJoinOrder::cal_dimension_info(const uint64_t table_id, //alias table id
|
||||
LOG_WARN("index info entry should not be null", K(ret));
|
||||
} else {
|
||||
ObSEArray<uint64_t, 8> filter_column_ids;
|
||||
bool is_index_back = index_info_entry->is_index_back();
|
||||
bool is_index_back = ignore_index_back_dim ? false : index_info_entry->is_index_back();
|
||||
const OrderingInfo *ordering_info = &index_info_entry->get_ordering_info();
|
||||
ObSEArray<uint64_t, 8> interest_column_ids;
|
||||
ObSEArray<bool, 8> const_column_info;
|
||||
@ -2501,10 +2502,6 @@ int ObJoinOrder::cal_dimension_info(const uint64_t table_id, //alias table id
|
||||
* */
|
||||
bool can_extract_range = prefix_range_ids.count() > 0 || contain_always_false;
|
||||
if (OB_FAIL(index_dim.add_index_back_dim(is_index_back,
|
||||
interest_column_ids.count() > 0,
|
||||
can_extract_range,
|
||||
index_schema->get_column_count(),
|
||||
filter_column_ids,
|
||||
*allocator_))) {
|
||||
LOG_WARN("add index back dim failed", K(is_index_back), K(ret));
|
||||
} else if (OB_FAIL(index_dim.add_interesting_order_dim(is_index_back,
|
||||
@ -2546,7 +2543,8 @@ int ObJoinOrder::skyline_prunning_index(const uint64_t table_id,
|
||||
const ObIndexInfoCache &index_info_cache,
|
||||
const ObIArray<uint64_t> &valid_index_ids,
|
||||
ObIArray<uint64_t> &skyline_index_ids,
|
||||
ObIArray<ObRawExpr *> &restrict_infos)
|
||||
ObIArray<ObRawExpr *> &restrict_infos,
|
||||
bool ignore_index_back_dim)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!do_prunning) {
|
||||
@ -2576,7 +2574,8 @@ int ObJoinOrder::skyline_prunning_index(const uint64_t table_id,
|
||||
base_table_id,
|
||||
tid, stmt,
|
||||
*index_dim, index_info_cache,
|
||||
restrict_infos))) {
|
||||
restrict_infos,
|
||||
ignore_index_back_dim))) {
|
||||
LOG_WARN("Failed to cal dimension info", K(ret), "index_id", valid_index_ids, K(i));
|
||||
} else if (OB_FAIL(recorder.add_index_dim(*index_dim, has_add))) {
|
||||
LOG_WARN("failed to add index dimension", K(ret));
|
||||
@ -8889,14 +8888,23 @@ int ObJoinOrder::generate_base_table_paths(PathHelper &helper)
|
||||
if (!helper.is_inner_path_ &&
|
||||
OB_FAIL(compute_base_table_property(table_id, ref_table_id))) {
|
||||
LOG_WARN("failed to compute base path property", K(ret));
|
||||
} else if (OB_FAIL(create_access_paths(table_id, ref_table_id, helper, access_paths, index_info_cache))) {
|
||||
} else if (OB_FAIL(create_access_paths(table_id,
|
||||
ref_table_id,
|
||||
helper,
|
||||
access_paths,
|
||||
index_info_cache))) {
|
||||
LOG_WARN("failed to add table to join order(single)", K(ret));
|
||||
} else if (OB_FAIL(set_table_location_for_paths(access_paths,
|
||||
index_info_cache))) {
|
||||
LOG_WARN("failed to calc table location", K(ret));
|
||||
} else if (OB_FAIL(estimate_size_for_base_table(helper, access_paths))) {
|
||||
LOG_WARN("failed to estimate_size", K(ret));
|
||||
} else if (OB_FAIL(pruning_unstable_access_path(helper.table_opt_info_, access_paths))) {
|
||||
} else if (OB_FAIL(pruning_unstable_access_path(table_id,
|
||||
ref_table_id,
|
||||
helper,
|
||||
index_info_cache,
|
||||
helper.table_opt_info_,
|
||||
access_paths))) {
|
||||
LOG_WARN("failed to pruning unstable access path", K(ret));
|
||||
} else if (OB_FAIL(compute_parallel_and_server_info_for_base_paths(access_paths))) {
|
||||
LOG_WARN("failed to compute", K(ret));
|
||||
@ -8958,7 +8966,11 @@ int ObJoinOrder::compute_base_table_property(uint64_t table_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJoinOrder::pruning_unstable_access_path(BaseTableOptInfo *table_opt_info,
|
||||
int ObJoinOrder::pruning_unstable_access_path(const uint64_t table_id,
|
||||
const uint64_t ref_table_id,
|
||||
PathHelper &helper,
|
||||
ObIndexInfoCache &index_info_cache,
|
||||
BaseTableOptInfo *table_opt_info,
|
||||
ObIArray<AccessPath *> &access_paths)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -8966,7 +8978,12 @@ int ObJoinOrder::pruning_unstable_access_path(BaseTableOptInfo *table_opt_info,
|
||||
ObSEArray<uint64_t, 4> unstable_index_id;
|
||||
if (access_paths.count() <= 1) {
|
||||
/* do not pruning access path */
|
||||
} else if (OB_FAIL(try_pruning_base_table_access_path(access_paths, unstable_index_id))) {
|
||||
} else if (OB_FAIL(try_pruning_base_table_access_path(table_id,
|
||||
ref_table_id,
|
||||
helper,
|
||||
index_info_cache,
|
||||
access_paths,
|
||||
unstable_index_id))) {
|
||||
LOG_WARN("failed to pruning base table access path", K(ret));
|
||||
}
|
||||
|
||||
@ -8995,21 +9012,32 @@ int ObJoinOrder::pruning_unstable_access_path(BaseTableOptInfo *table_opt_info,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObJoinOrder::try_pruning_base_table_access_path(ObIArray<AccessPath*> &access_paths,
|
||||
int ObJoinOrder::try_pruning_base_table_access_path(const uint64_t table_id,
|
||||
const uint64_t ref_table_id,
|
||||
PathHelper &helper,
|
||||
ObIndexInfoCache &index_info_cache,
|
||||
ObIArray<AccessPath*> &access_paths,
|
||||
ObIArray<uint64_t> &unstable_index_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool need_prune = false;
|
||||
ObSEArray<int64_t, 2> base_path_positions;
|
||||
ObSEArray<int64_t, 2> none_range_path_positions;
|
||||
AccessPath *ap = NULL;
|
||||
const QueryRangeInfo *query_range_info = NULL;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < access_paths.count(); ++i) {
|
||||
if (OB_ISNULL(ap = access_paths.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else if (ap->ref_table_id_ == ap->index_id_) {
|
||||
if (OB_FAIL(base_path_positions.push_back(i))) {
|
||||
LOG_WARN("failed to push back pos", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(index_info_cache.get_query_range(table_id, ap->index_id_,
|
||||
query_range_info))) {
|
||||
LOG_WARN("get_range_columns failed", K(ret));
|
||||
} else if (OB_ISNULL(query_range_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("query_range_info should not be null", K(ret));
|
||||
} else if (ap->range_prefix_count_ <= 0 &&
|
||||
!query_range_info->get_contain_always_false() &&
|
||||
OB_FAIL(none_range_path_positions.push_back(i))) {
|
||||
LOG_WARN("failed to push back pos", K(ret));
|
||||
} else {
|
||||
need_prune |= ap->range_prefix_count_ > 0 &&
|
||||
ap->get_logical_query_range_row_count() < PRUNING_ROW_COUNT_THRESHOLD;
|
||||
@ -9019,8 +9047,8 @@ int ObJoinOrder::try_pruning_base_table_access_path(ObIArray<AccessPath*> &acces
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && need_prune) {
|
||||
for (int64_t i = base_path_positions.count() - 1; OB_SUCC(ret) && i >= 0; --i) {
|
||||
int64_t base_path_pos = base_path_positions.at(i);
|
||||
for (int64_t i = none_range_path_positions.count() - 1; OB_SUCC(ret) && i >= 0; --i) {
|
||||
int64_t base_path_pos = none_range_path_positions.at(i);
|
||||
if (OB_ISNULL(ap = access_paths.at(base_path_pos))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected pos or access path", K(ret), K(base_path_pos),
|
||||
@ -9032,11 +9060,51 @@ int ObJoinOrder::try_pruning_base_table_access_path(ObIArray<AccessPath*> &acces
|
||||
} else if (OB_FAIL(unstable_index_id.push_back(ap->index_id_))) {
|
||||
LOG_WARN("failed to push back index id", K(ret));
|
||||
} else {
|
||||
LOG_TRACE("pruned base table access paths", K(*ap));
|
||||
LOG_TRACE("pruned none query range access paths", K(*ap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObSEArray<uint64_t, 8> valid_index_ids;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < access_paths.count(); ++i) {
|
||||
if (OB_ISNULL(ap = access_paths.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else if (ObOptimizerUtil::find_item(valid_index_ids, ap->index_id_)) {
|
||||
} else if (OB_FAIL(valid_index_ids.push_back(ap->index_id_))) {
|
||||
LOG_WARN("failed to push back index id", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && need_prune) {
|
||||
const ObDMLStmt *stmt = NULL;
|
||||
ObSEArray<uint64_t, 8> skyline_index_ids;
|
||||
if (OB_ISNULL(get_plan()) ||
|
||||
OB_ISNULL(stmt = get_plan()->get_stmt())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null stmt", K(ret));
|
||||
} else if (OB_FAIL(skyline_prunning_index(table_id,
|
||||
ref_table_id,
|
||||
stmt,
|
||||
true,
|
||||
index_info_cache,
|
||||
valid_index_ids,
|
||||
skyline_index_ids,
|
||||
helper.filters_,
|
||||
true))) {
|
||||
LOG_WARN("failed to pruning_index", K(table_id), K(ref_table_id), K(ret));
|
||||
}
|
||||
for (int i = access_paths.count() - 1; OB_SUCC(ret) && i >= 0; --i) {
|
||||
if (OB_ISNULL(ap = access_paths.at(i))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null", K(ret));
|
||||
} else if (ObOptimizerUtil::find_item(skyline_index_ids, ap->index_id_)) {
|
||||
} else if (OB_FAIL(unstable_index_id.push_back(ap->index_id_))) {
|
||||
LOG_WARN("failed to push back index id", K(ret));
|
||||
} else if (OB_FAIL(access_paths.remove(i))) {
|
||||
LOG_WARN("failed to remove access path", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1381,11 +1381,20 @@ struct NullAwareAntiJoinInfo {
|
||||
const ObIndexInfoCache &index_info_cache,
|
||||
const common::ObIArray<uint64_t> &valid_index_ids,
|
||||
common::ObIArray<uint64_t> &skyline_index_ids,
|
||||
ObIArray<ObRawExpr *> &restrict_infos);
|
||||
ObIArray<ObRawExpr *> &restrict_infos,
|
||||
bool ignore_index_back_dim = false);
|
||||
|
||||
int pruning_unstable_access_path(BaseTableOptInfo *table_opt_info,
|
||||
int pruning_unstable_access_path(const uint64_t table_id,
|
||||
const uint64_t ref_table_id,
|
||||
PathHelper &helper,
|
||||
ObIndexInfoCache &index_info_cache,
|
||||
BaseTableOptInfo *table_opt_info,
|
||||
ObIArray<AccessPath *> &access_paths);
|
||||
int try_pruning_base_table_access_path(ObIArray<AccessPath*> &access_paths,
|
||||
int try_pruning_base_table_access_path(const uint64_t table_id,
|
||||
const uint64_t ref_table_id,
|
||||
PathHelper &helper,
|
||||
ObIndexInfoCache &index_info_cache,
|
||||
ObIArray<AccessPath*> &access_paths,
|
||||
ObIArray<uint64_t> &unstable_index_id);
|
||||
|
||||
int cal_dimension_info(const uint64_t table_id,
|
||||
@ -1394,7 +1403,8 @@ struct NullAwareAntiJoinInfo {
|
||||
const ObDMLStmt *stmt,
|
||||
ObIndexSkylineDim &index_dim,
|
||||
const ObIndexInfoCache &index_info_cache,
|
||||
ObIArray<ObRawExpr *> &restrict_infos);
|
||||
ObIArray<ObRawExpr *> &restrict_infos,
|
||||
bool ignore_index_back_dim = false);
|
||||
|
||||
int fill_index_info_entry(const uint64_t table_id,
|
||||
const uint64_t base_table_id,
|
||||
|
@ -38,59 +38,14 @@ int ObIndexBackDim::compare(const ObSkylineDim &other, CompareStat &status) cons
|
||||
if (need_index_back_ == tmp.need_index_back_) {
|
||||
status = EQUAL;
|
||||
} else if (!need_index_back_ && tmp.need_index_back_) {
|
||||
status = UNCOMPARABLE;
|
||||
//在都抽不出query range和 没有 interesting order的情况下
|
||||
//我们考虑两边的列的大小
|
||||
//只有左边的restrict info是右边的super set的情况下
|
||||
//并且 左边的列比右边的列少的情况下
|
||||
//左边才算dominated右边
|
||||
if (!has_interesting_order_ && !can_extract_range_
|
||||
&& !tmp.has_interesting_order_ && !tmp.can_extract_range_) {
|
||||
//both not interesting order and not extract range
|
||||
if (tmp.filter_column_cnt_ == 0) {
|
||||
//右边抽不出条件,会走索引全表扫描+ 回表 剪掉
|
||||
status = LEFT_DOMINATED;
|
||||
} else if (index_column_cnt_ <= tmp.index_column_cnt_) {
|
||||
status = LEFT_DOMINATED;
|
||||
}
|
||||
} else {
|
||||
status = LEFT_DOMINATED;
|
||||
}
|
||||
status = LEFT_DOMINATED;
|
||||
} else if (need_index_back_ && !tmp.need_index_back_) {
|
||||
status = UNCOMPARABLE;
|
||||
if (!has_interesting_order_ && !can_extract_range_
|
||||
&& !tmp.has_interesting_order_ && !tmp.can_extract_range_) {
|
||||
if (0 == filter_column_cnt_) {
|
||||
//左边抽不出条件,会走索引全表扫描+回表, 剪掉
|
||||
status = RIGHT_DOMINATED;
|
||||
} else if (index_column_cnt_ >= tmp.index_column_cnt_) {
|
||||
status = RIGHT_DOMINATED;
|
||||
}
|
||||
} else {
|
||||
status = RIGHT_DOMINATED;
|
||||
}
|
||||
status = RIGHT_DOMINATED;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObIndexBackDim::add_filter_column_ids(const common::ObIArray<uint64_t> &filter_column_ids)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (filter_column_ids.count() < 0 || filter_column_ids.count() > OB_USER_MAX_ROWKEY_COLUMN_NUMBER) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("too many columns", K(ret), K(filter_column_ids.count()));
|
||||
} else {
|
||||
MEMSET(filter_column_ids_, 0, sizeof(uint64_t) * OB_USER_MAX_ROWKEY_COLUMN_NUMBER);
|
||||
for (int i = 0; OB_SUCC(ret) && i < filter_column_ids.count(); ++i) {
|
||||
filter_column_ids_[i] = filter_column_ids.at(i);
|
||||
}
|
||||
filter_column_cnt_ = filter_column_ids.count();
|
||||
lib::ob_sort(filter_column_ids_, filter_column_ids_ + filter_column_cnt_);//do sort, for quick compare
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObInterestOrderDim::add_filter_column_ids(const common::ObIArray<uint64_t> &filter_column_ids)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -506,10 +461,6 @@ int ObIndexSkylineDim::add_skyline_dim(const ObSkylineDim &dim)
|
||||
}
|
||||
|
||||
int ObIndexSkylineDim::add_index_back_dim(const bool is_index_back,
|
||||
const bool has_interest_order,
|
||||
const bool can_extract_range,
|
||||
const int64_t index_column_cnt,
|
||||
const ObIArray<uint64_t> &filter_column_ids,
|
||||
ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -521,20 +472,10 @@ int ObIndexSkylineDim::add_index_back_dim(const bool is_index_back,
|
||||
LOG_WARN("failed to create dimension", K(ret));
|
||||
} else {
|
||||
dim->set_index_back(is_index_back);
|
||||
dim->set_interesting_order(has_interest_order);
|
||||
dim->set_extract_range(can_extract_range);
|
||||
dim->set_index_column_cnt(index_column_cnt);
|
||||
if (!has_interest_order && !can_extract_range && is_index_back) {
|
||||
if (OB_FAIL(dim->add_filter_column_ids(filter_column_ids))) {
|
||||
LOG_WARN("failed to add restrcit_ids", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(add_skyline_dim(*dim))) {
|
||||
LOG_WARN("failed to add skyline dimension", K(ret));
|
||||
} else {
|
||||
LOG_TRACE("add index back dim success", K(ret), K(*dim));
|
||||
}
|
||||
if (OB_FAIL(add_skyline_dim(*dim))) {
|
||||
LOG_WARN("failed to add skyline dimension", K(ret));
|
||||
} else {
|
||||
LOG_TRACE("add index back dim success", K(ret), K(*dim));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -64,31 +64,15 @@ class ObIndexBackDim : public ObSkylineDim
|
||||
{
|
||||
public:
|
||||
friend class ObOptimizerTraceImpl;
|
||||
ObIndexBackDim() : ObSkylineDim(INDEX_BACK), need_index_back_(false),
|
||||
has_interesting_order_(true),
|
||||
can_extract_range_(true),
|
||||
index_column_cnt_(0),
|
||||
filter_column_cnt_(0)
|
||||
{ MEMSET(filter_column_ids_, 0, sizeof(uint64_t) * common::OB_USER_MAX_ROWKEY_COLUMN_NUMBER); }
|
||||
ObIndexBackDim() : ObSkylineDim(INDEX_BACK), need_index_back_(false)
|
||||
{}
|
||||
|
||||
virtual ~ObIndexBackDim() {}
|
||||
void set_index_back(const bool index_back) { need_index_back_ = index_back; }
|
||||
void set_interesting_order(const bool has) { has_interesting_order_ = has; }
|
||||
void set_extract_range(const bool can) { can_extract_range_ = can;}
|
||||
void set_index_column_cnt(const int64_t size) { index_column_cnt_ = size; }
|
||||
int add_filter_column_ids(const common::ObIArray<uint64_t> &filter_column_ids);
|
||||
virtual int compare(const ObSkylineDim &other, CompareStat &status) const;
|
||||
VIRTUAL_TO_STRING_KV(K_(need_index_back), K_(has_interesting_order), K_(can_extract_range),
|
||||
K_(index_column_cnt),
|
||||
"restrcit_ids", common::ObArrayWrap<uint64_t>(filter_column_ids_, filter_column_cnt_));
|
||||
VIRTUAL_TO_STRING_KV(K_(need_index_back));
|
||||
private:
|
||||
bool need_index_back_;
|
||||
bool has_interesting_order_;
|
||||
bool can_extract_range_;
|
||||
int64_t index_column_cnt_;
|
||||
//some filter conditions on index columns
|
||||
int64_t filter_column_cnt_;
|
||||
uint64_t filter_column_ids_[common::OB_USER_MAX_ROWKEY_COLUMN_NUMBER];
|
||||
};
|
||||
|
||||
|
||||
@ -222,10 +206,6 @@ public:
|
||||
int add_skyline_dim(const ObSkylineDim &dim);
|
||||
void set_index_id(const uint64_t index_id) { index_id_ = index_id; }
|
||||
int add_index_back_dim(const bool is_index_back,
|
||||
const bool has_interest_order,
|
||||
const bool can_extract_range,
|
||||
const int64_t index_column_cnt,
|
||||
const common::ObIArray<uint64_t> &restrict_ids,
|
||||
common::ObIAllocator &allocator);
|
||||
int add_interesting_order_dim(const bool is_index_back,
|
||||
const bool can_extract_range,
|
||||
|
@ -217,20 +217,21 @@ Outputs & filters:
|
||||
range_key([t1.b], [t1.c], [t1.pk1]), range(MIN,MIN,MIN ; MAX,MAX,MAX)always true
|
||||
explain select distinct(b),c from t1 where a > 100;
|
||||
Query Plan
|
||||
==========================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------------------
|
||||
|0 |MERGE DISTINCT | |1 |3 |
|
||||
|1 |└─TABLE FULL SCAN|t1(idx_b_c_a)|1 |3 |
|
||||
==========================================================
|
||||
===========================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
-----------------------------------------------------------
|
||||
|0 |HASH DISTINCT | |1 |3 |
|
||||
|1 |└─TABLE RANGE SCAN|t1(idx_a_b_c)|1 |3 |
|
||||
===========================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.b], [t1.c]), filter(nil), rowset=16
|
||||
distinct([t1.b], [t1.c])
|
||||
1 - output([t1.b], [t1.c]), filter([t1.a > 100]), rowset=16
|
||||
access([t1.a], [t1.b], [t1.c]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.b], [t1.c], [t1.a], [t1.pk1]), range(MIN,MIN,MIN,MIN ; MAX,MAX,MAX,MAX)always true
|
||||
1 - output([t1.b], [t1.c]), filter(nil), rowset=16
|
||||
access([t1.b], [t1.c]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t1.a], [t1.b], [t1.c], [t1.pk1]), range(100,MAX,MAX,MAX ; MAX,MAX,MAX,MAX),
|
||||
range_cond([t1.a > 100])
|
||||
explain select distinct(c),b from t1;
|
||||
Query Plan
|
||||
========================================================
|
||||
@ -249,23 +250,24 @@ Outputs & filters:
|
||||
range_key([t1.b], [t1.c], [t1.pk1]), range(MIN,MIN,MIN ; MAX,MAX,MAX)always true
|
||||
explain select distinct(c),b, d from t1 where b > 200 limit 100;
|
||||
Query Plan
|
||||
============================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
------------------------------------------------------------
|
||||
|0 |LIMIT | |1 |5 |
|
||||
|1 |└─HASH DISTINCT | |1 |5 |
|
||||
|2 | └─TABLE FULL SCAN|t1(idx_c_a_b)|1 |5 |
|
||||
============================================================
|
||||
===========================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
-----------------------------------------------------------
|
||||
|0 |LIMIT | |1 |8 |
|
||||
|1 |└─HASH DISTINCT | |1 |8 |
|
||||
|2 | └─TABLE RANGE SCAN|t1(idx_b_c)|1 |7 |
|
||||
===========================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.c], [t1.b], [t1.d]), filter(nil), rowset=16
|
||||
limit(100), offset(nil)
|
||||
1 - output([t1.c], [t1.b], [t1.d]), filter(nil), rowset=16
|
||||
distinct([t1.c], [t1.b], [t1.d])
|
||||
2 - output([t1.b], [t1.c], [t1.d]), filter([t1.b > 200]), rowset=16
|
||||
2 - output([t1.b], [t1.c], [t1.d]), filter(nil), rowset=16
|
||||
access([t1.pk1], [t1.b], [t1.c], [t1.d]), partitions(p0)
|
||||
is_index_back=true, is_global_index=false, filter_before_indexback[true],
|
||||
range_key([t1.c], [t1.a], [t1.b], [t1.pk1]), range(MIN,MIN,MIN,MIN ; MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=true, is_global_index=false,
|
||||
range_key([t1.b], [t1.c], [t1.pk1]), range(200,MAX,MAX ; MAX,MAX,MAX),
|
||||
range_cond([t1.b > 200])
|
||||
explain select b from t1 order by b;
|
||||
Query Plan
|
||||
====================================================
|
||||
@ -1536,30 +1538,42 @@ Outputs & filters:
|
||||
range_key([t1.b], [t1.c], [t1.a], [t1.pk1]), range(MAX,MAX,MAX,MAX ; MIN,MIN,MIN,MIN)always false
|
||||
explain select a, b, c from t1 where b = 100 or (b = 200 and c = 300) order by c desc limit 0, 100;
|
||||
Query Plan
|
||||
================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------------------------
|
||||
|0 |TABLE FULL SCAN|t1(idx_c_a_b,Reverse)|1 |3 |
|
||||
================================================================
|
||||
============================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
------------------------------------------------------------
|
||||
|0 |LIMIT | |1 |5 |
|
||||
|1 |└─TOP-N SORT | |1 |5 |
|
||||
|2 | └─TABLE FULL SCAN|t1(idx_b_c_a)|1 |5 |
|
||||
============================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.a], [t1.b], [t1.c]), filter([t1.b = 100 OR t1.b = 200 AND t1.c = 300]), rowset=16
|
||||
0 - output([t1.a], [t1.b], [t1.c]), filter(nil), rowset=16
|
||||
limit(100), offset(0)
|
||||
1 - output([t1.a], [t1.b], [t1.c]), filter(nil), rowset=16
|
||||
sort_keys([t1.c, DESC]), topn(100 + 0)
|
||||
2 - output([t1.b], [t1.c], [t1.a]), filter([t1.b = 100 OR t1.b = 200 AND t1.c = 300]), rowset=16
|
||||
access([t1.b], [t1.c], [t1.a]), partitions(p0)
|
||||
limit(100), offset(0), is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.c], [t1.a], [t1.b], [t1.pk1]), range(MIN,MIN,MIN,MIN ; MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.b], [t1.c], [t1.a], [t1.pk1]), range(100,MIN,MIN,MIN ; 100,MAX,MAX,MAX), (200,300,MIN,MIN ; 200,300,MAX,MAX)
|
||||
explain select a, b, c from t1 where (b = 200 and c = 300) or (b = 100) order by c desc limit 0, 100;
|
||||
Query Plan
|
||||
================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------------------------
|
||||
|0 |TABLE FULL SCAN|t1(idx_c_a_b,Reverse)|1 |3 |
|
||||
================================================================
|
||||
============================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
------------------------------------------------------------
|
||||
|0 |LIMIT | |1 |5 |
|
||||
|1 |└─TOP-N SORT | |1 |5 |
|
||||
|2 | └─TABLE FULL SCAN|t1(idx_b_c_a)|1 |5 |
|
||||
============================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([t1.a], [t1.b], [t1.c]), filter([t1.b = 200 AND t1.c = 300 OR t1.b = 100]), rowset=16
|
||||
0 - output([t1.a], [t1.b], [t1.c]), filter(nil), rowset=16
|
||||
limit(100), offset(0)
|
||||
1 - output([t1.a], [t1.b], [t1.c]), filter(nil), rowset=16
|
||||
sort_keys([t1.c, DESC]), topn(100 + 0)
|
||||
2 - output([t1.b], [t1.c], [t1.a]), filter([t1.b = 200 AND t1.c = 300 OR t1.b = 100]), rowset=16
|
||||
access([t1.b], [t1.c], [t1.a]), partitions(p0)
|
||||
limit(100), offset(0), is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.c], [t1.a], [t1.b], [t1.pk1]), range(MIN,MIN,MIN,MIN ; MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([t1.b], [t1.c], [t1.a], [t1.pk1]), range(200,300,MIN,MIN ; 200,300,MAX,MAX), (100,MIN,MIN,MIN ; 100,MAX,MAX,MAX)
|
||||
explain select a1, a2, b, min(c), max(c) from t4 group by a1, a2, b;
|
||||
Query Plan
|
||||
=========================================================
|
||||
|
@ -1002,44 +1002,40 @@ Outputs & filters:
|
||||
range_cond([skyline_int.v3 = 100], [skyline_int.v4 = 100], [skyline_int.v5 = 100])
|
||||
explain select v3, v4, v5 from skyline_int where v3 in (100, 200, 300) group by v3, v4, v5 order by v3, v4, v5;
|
||||
Query Plan
|
||||
===========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
---------------------------------------------------------------------------
|
||||
|0 |SORT | |1 |3 |
|
||||
|1 |└─HASH DISTINCT | |1 |3 |
|
||||
|2 | └─TABLE FULL SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
===========================================================================
|
||||
==========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------------------------------------
|
||||
|0 |MERGE DISTINCT | |1 |7 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v3_v4_v5_v2)|1 |7 |
|
||||
==========================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter(nil), rowset=16
|
||||
sort_keys([skyline_int.v3, ASC], [skyline_int.v4, ASC], [skyline_int.v5, ASC])
|
||||
1 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter(nil), rowset=16
|
||||
distinct([skyline_int.v3], [skyline_int.v4], [skyline_int.v5])
|
||||
2 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter([skyline_int.v3 IN (100, 200, 300)]), rowset=16
|
||||
1 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter(nil), rowset=16
|
||||
access([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(MIN,MIN,MIN,MIN,
|
||||
MIN,MIN ; MAX,MAX,MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v3], [skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MIN,MIN,MIN,
|
||||
MIN,MIN ; 100,MAX,MAX,MAX,MAX,MAX), (200,MIN,MIN,MIN,MIN,MIN ; 200,MAX,MAX,MAX,MAX,MAX), (300,MIN,MIN,MIN,MIN,MIN ; 300,MAX,MAX,MAX,MAX,MAX),
|
||||
range_cond([skyline_int.v3 IN (100, 200, 300)])
|
||||
explain select distinct v3, v4, v5 from skyline_int where v3 in (100, 200, 300) order by v3, v4, v5;
|
||||
Query Plan
|
||||
===========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
---------------------------------------------------------------------------
|
||||
|0 |SORT | |1 |3 |
|
||||
|1 |└─HASH DISTINCT | |1 |3 |
|
||||
|2 | └─TABLE FULL SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
===========================================================================
|
||||
==========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------------------------------------
|
||||
|0 |MERGE DISTINCT | |1 |7 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v3_v4_v5_v2)|1 |7 |
|
||||
==========================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter(nil), rowset=16
|
||||
sort_keys([skyline_int.v3, ASC], [skyline_int.v4, ASC], [skyline_int.v5, ASC])
|
||||
1 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter(nil), rowset=16
|
||||
distinct([skyline_int.v3], [skyline_int.v4], [skyline_int.v5])
|
||||
2 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter([skyline_int.v3 IN (100, 200, 300)]), rowset=16
|
||||
1 - output([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), filter(nil), rowset=16
|
||||
access([skyline_int.v3], [skyline_int.v4], [skyline_int.v5]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(MIN,MIN,MIN,MIN,
|
||||
MIN,MIN ; MAX,MAX,MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v3], [skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MIN,MIN,MIN,
|
||||
MIN,MIN ; 100,MAX,MAX,MAX,MAX,MAX), (200,MIN,MIN,MIN,MIN,MIN ; 200,MAX,MAX,MAX,MAX,MAX), (300,MIN,MIN,MIN,MIN,MIN ; 300,MAX,MAX,MAX,MAX,MAX),
|
||||
range_cond([skyline_int.v3 IN (100, 200, 300)])
|
||||
explain select v3, v4, v5 from skyline_int where v3 = 100 and v4 > 100 group by v4, v3, v5;
|
||||
Query Plan
|
||||
==========================================================================
|
||||
@ -1060,38 +1056,40 @@ Outputs & filters:
|
||||
range_cond([skyline_int.v3 = 100], [skyline_int.v4 > 100])
|
||||
explain select v4, v5, v6 from skyline_int where v3 = 100 group by v3, v5;
|
||||
Query Plan
|
||||
============================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------------------------------------
|
||||
|0 |MERGE GROUP BY | |1 |3 |
|
||||
|1 |└─TABLE FULL SCAN|skyline_int(idx_v5_v6_v2_v3_v4)|1 |3 |
|
||||
============================================================================
|
||||
=============================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
-----------------------------------------------------------------------------
|
||||
|0 |HASH GROUP BY | |1 |3 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v3_v4_v5_v6_v2)|1 |3 |
|
||||
=============================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v4], [skyline_int.v5], [skyline_int.v6]), filter(nil), rowset=16
|
||||
group([skyline_int.v5]), agg_func(nil)
|
||||
1 - output([skyline_int.v4], [skyline_int.v5], [skyline_int.v6]), filter([skyline_int.v3 = 100]), rowset=16
|
||||
access([skyline_int.v3], [skyline_int.v4], [skyline_int.v5], [skyline_int.v6]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([skyline_int.v5], [skyline_int.v6], [skyline_int.v2], [skyline_int.v3], [skyline_int.v4], [skyline_int.v1], [skyline_int.tenant_id]), range(MIN,
|
||||
MIN,MIN,MIN,MIN,MIN,MIN ; MAX,MAX,MAX,MAX,MAX,MAX,MAX)always true
|
||||
1 - output([skyline_int.v4], [skyline_int.v5], [skyline_int.v6]), filter(nil), rowset=16
|
||||
access([skyline_int.v4], [skyline_int.v5], [skyline_int.v6]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v3], [skyline_int.v4], [skyline_int.v5], [skyline_int.v6], [skyline_int.v2], [skyline_int.v1], [skyline_int.tenant_id]), range(100,
|
||||
MIN,MIN,MIN,MIN,MIN,MIN ; 100,MAX,MAX,MAX,MAX,MAX,MAX),
|
||||
range_cond([skyline_int.v3 = 100])
|
||||
explain select distinct v3, v5 from skyline_int where v4 = 100;
|
||||
Query Plan
|
||||
=========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------------------------------------
|
||||
|0 |MERGE DISTINCT | |1 |3 |
|
||||
|1 |└─TABLE FULL SCAN|skyline_int(idx_v3_v4_v5_v2)|1 |3 |
|
||||
=========================================================================
|
||||
==========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------------------------------------
|
||||
|0 |HASH DISTINCT | |1 |3 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
==========================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
distinct([skyline_int.v3], [skyline_int.v5])
|
||||
1 - output([skyline_int.v3], [skyline_int.v5]), filter([skyline_int.v4 = 100]), rowset=16
|
||||
access([skyline_int.v4], [skyline_int.v3], [skyline_int.v5]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([skyline_int.v3], [skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v1], [skyline_int.tenant_id]), range(MIN,MIN,MIN,MIN,
|
||||
MIN,MIN ; MAX,MAX,MAX,MAX,MAX,MAX)always true
|
||||
1 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
access([skyline_int.v3], [skyline_int.v5]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MIN,MIN,MIN,
|
||||
MIN,MIN ; 100,MAX,MAX,MAX,MAX,MAX),
|
||||
range_cond([skyline_int.v4 = 100])
|
||||
explain select distinct v3, v5 from skyline_int where v4 > 100 and v4 < 200;
|
||||
Query Plan
|
||||
==========================================================================
|
||||
@ -1112,77 +1110,73 @@ Outputs & filters:
|
||||
range_cond([skyline_int.v4 > 100], [skyline_int.v4 < 200])
|
||||
explain select v3, v5 from skyline_int where v4 > 100 and v4 < 200 order by v4, v2;
|
||||
Query Plan
|
||||
==========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------------------------------------
|
||||
|0 |SORT | |1 |3 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
==========================================================================
|
||||
=====================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
---------------------------------------------------------------------
|
||||
|0 |TABLE RANGE SCAN|skyline_int(idx_v4_v2_v3)|1 |7 |
|
||||
=====================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
sort_keys([skyline_int.v4, ASC], [skyline_int.v2, ASC]), prefix_pos(1)
|
||||
1 - output([skyline_int.v4], [skyline_int.v3], [skyline_int.v5], [skyline_int.v2]), filter(nil), rowset=16
|
||||
access([skyline_int.v4], [skyline_int.v3], [skyline_int.v5], [skyline_int.v2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MAX,MAX,MAX,
|
||||
MAX,MAX ; 200,MIN,MIN,MIN,MIN,MIN),
|
||||
access([skyline_int.v1], [skyline_int.tenant_id], [skyline_int.v3], [skyline_int.v5]), partitions(p0)
|
||||
is_index_back=true, is_global_index=false,
|
||||
range_key([skyline_int.v4], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MAX,MAX,MAX,MAX ; 200,MIN,MIN,
|
||||
MIN,MIN),
|
||||
range_cond([skyline_int.v4 > 100], [skyline_int.v4 < 200])
|
||||
explain select v3, v5 from skyline_int where v4 > 100 and v4 < 200 order by v4, v2 limit 100;
|
||||
Query Plan
|
||||
==========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------------------------------------
|
||||
|0 |TOP-N SORT | |1 |3 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
==========================================================================
|
||||
=====================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
---------------------------------------------------------------------
|
||||
|0 |TABLE RANGE SCAN|skyline_int(idx_v4_v2_v3)|1 |7 |
|
||||
=====================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
sort_keys([skyline_int.v4, ASC], [skyline_int.v2, ASC]), topn(100), prefix_pos(1)
|
||||
1 - output([skyline_int.v4], [skyline_int.v3], [skyline_int.v5], [skyline_int.v2]), filter(nil), rowset=16
|
||||
access([skyline_int.v4], [skyline_int.v3], [skyline_int.v5], [skyline_int.v2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MAX,MAX,MAX,
|
||||
MAX,MAX ; 200,MIN,MIN,MIN,MIN,MIN),
|
||||
access([skyline_int.v1], [skyline_int.tenant_id], [skyline_int.v3], [skyline_int.v5]), partitions(p0)
|
||||
limit(100), offset(nil), is_index_back=true, is_global_index=false,
|
||||
range_key([skyline_int.v4], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MAX,MAX,MAX,MAX ; 200,MIN,MIN,
|
||||
MIN,MIN),
|
||||
range_cond([skyline_int.v4 > 100], [skyline_int.v4 < 200])
|
||||
explain select v3, v5 from skyline_int where v5 = 100 group by v4, v2;
|
||||
Query Plan
|
||||
=========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
-------------------------------------------------------------------------
|
||||
|0 |MERGE GROUP BY | |1 |3 |
|
||||
|1 |└─TABLE FULL SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
=========================================================================
|
||||
==========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
--------------------------------------------------------------------------
|
||||
|0 |HASH GROUP BY | |1 |3 |
|
||||
|1 |└─TABLE RANGE SCAN|skyline_int(idx_v5_v2_v3_v4)|1 |3 |
|
||||
==========================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
group([skyline_int.v4], [skyline_int.v2]), agg_func(nil)
|
||||
1 - output([skyline_int.v5], [skyline_int.v3], [skyline_int.v4], [skyline_int.v2]), filter([skyline_int.v5 = 100]), rowset=16
|
||||
1 - output([skyline_int.v5], [skyline_int.v3], [skyline_int.v4], [skyline_int.v2]), filter(nil), rowset=16
|
||||
access([skyline_int.v5], [skyline_int.v3], [skyline_int.v4], [skyline_int.v2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(MIN,MIN,MIN,MIN,
|
||||
MIN,MIN ; MAX,MAX,MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v4], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MIN,MIN,MIN,
|
||||
MIN,MIN ; 100,MAX,MAX,MAX,MAX,MAX),
|
||||
range_cond([skyline_int.v5 = 100])
|
||||
explain select v3, v5 from skyline_int where v5 = 100 group by v4, v2 limit 100;
|
||||
Query Plan
|
||||
===========================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
---------------------------------------------------------------------------
|
||||
|0 |LIMIT | |1 |3 |
|
||||
|1 |└─MERGE GROUP BY | |1 |3 |
|
||||
|2 | └─TABLE FULL SCAN|skyline_int(idx_v4_v5_v2_v3)|1 |3 |
|
||||
===========================================================================
|
||||
============================================================================
|
||||
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
|
||||
----------------------------------------------------------------------------
|
||||
|0 |LIMIT | |1 |3 |
|
||||
|1 |└─HASH GROUP BY | |1 |3 |
|
||||
|2 | └─TABLE RANGE SCAN|skyline_int(idx_v5_v2_v3_v4)|1 |3 |
|
||||
============================================================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
limit(100), offset(nil)
|
||||
1 - output([skyline_int.v3], [skyline_int.v5]), filter(nil), rowset=16
|
||||
group([skyline_int.v4], [skyline_int.v2]), agg_func(nil)
|
||||
2 - output([skyline_int.v5], [skyline_int.v3], [skyline_int.v4], [skyline_int.v2]), filter([skyline_int.v5 = 100]), rowset=16
|
||||
2 - output([skyline_int.v5], [skyline_int.v3], [skyline_int.v4], [skyline_int.v2]), filter(nil), rowset=16
|
||||
access([skyline_int.v5], [skyline_int.v3], [skyline_int.v4], [skyline_int.v2]), partitions(p0)
|
||||
is_index_back=false, is_global_index=false, filter_before_indexback[false],
|
||||
range_key([skyline_int.v4], [skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v1], [skyline_int.tenant_id]), range(MIN,MIN,MIN,MIN,
|
||||
MIN,MIN ; MAX,MAX,MAX,MAX,MAX,MAX)always true
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([skyline_int.v5], [skyline_int.v2], [skyline_int.v3], [skyline_int.v4], [skyline_int.v1], [skyline_int.tenant_id]), range(100,MIN,MIN,MIN,
|
||||
MIN,MIN ; 100,MAX,MAX,MAX,MAX,MAX),
|
||||
range_cond([skyline_int.v5 = 100])
|
||||
explain select v3, v6 from skyline_int join other on skyline_int.v3 = other.c1 and skyline_int.v5 = other.c2 order by v3, v4;
|
||||
Query Plan
|
||||
================================================================================
|
||||
|
@ -311,21 +311,30 @@ Outputs & filters:
|
||||
insert into t1 values(1, 1), (2, 2);
|
||||
EXPLAIN BASIC update t1 set b=b+1 where a>0;
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME |
|
||||
-------------------------------------------
|
||||
|0 |DISTRIBUTED UPDATE | |
|
||||
|1 |└─DISTRIBUTED TABLE FULL SCAN|t1(gkey)|
|
||||
===========================================
|
||||
=========================================
|
||||
|ID|OPERATOR |NAME |
|
||||
-----------------------------------------
|
||||
|0 |DISTRIBUTED UPDATE | |
|
||||
|1 |└─PX COORDINATOR | |
|
||||
|2 | └─EXCHANGE OUT DISTR |:EX10000|
|
||||
|3 | └─PX PARTITION ITERATOR| |
|
||||
|4 | └─TABLE RANGE SCAN |t1 |
|
||||
=========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output(nil), filter(nil)
|
||||
table_columns([{t1: ({t1: (t1.a, t1.b)}, {gkey: (t1.b, t1.a)})}]),
|
||||
update([t1.b=column_conv(INT,PS:(11,0),NULL,cast(t1.b + 1, INT(-1, 0)))])
|
||||
1 - output([t1.a], [t1.b]), filter([t1.a > 0]), rowset=16
|
||||
access([t1.a], [t1.b]), partitions(p0)
|
||||
is_index_back=false, is_global_index=true, filter_before_indexback[false],
|
||||
range_key([t1.b], [t1.a]), range(MIN,MIN ; MAX,MAX)always true
|
||||
1 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
2 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
dop=1
|
||||
3 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
force partition granule
|
||||
4 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
access([t1.a], [t1.b]), partitions(p[0-2])
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t1.a]), range(0 ; MAX),
|
||||
range_cond([t1.a > 0])
|
||||
update t1 set b=b+1 where a>0;
|
||||
EXPLAIN BASIC select * from t1;
|
||||
Query Plan
|
||||
@ -369,21 +378,30 @@ Outputs & filters:
|
||||
insert into t1 values(1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||
EXPLAIN BASIC update t1 set b=b+1 where a>0;
|
||||
Query Plan
|
||||
===========================================
|
||||
|ID|OPERATOR |NAME |
|
||||
-------------------------------------------
|
||||
|0 |DISTRIBUTED UPDATE | |
|
||||
|1 |└─DISTRIBUTED TABLE FULL SCAN|t1(gkey)|
|
||||
===========================================
|
||||
=========================================
|
||||
|ID|OPERATOR |NAME |
|
||||
-----------------------------------------
|
||||
|0 |DISTRIBUTED UPDATE | |
|
||||
|1 |└─PX COORDINATOR | |
|
||||
|2 | └─EXCHANGE OUT DISTR |:EX10000|
|
||||
|3 | └─PX PARTITION ITERATOR| |
|
||||
|4 | └─TABLE RANGE SCAN |t1 |
|
||||
=========================================
|
||||
Outputs & filters:
|
||||
-------------------------------------
|
||||
0 - output(nil), filter(nil)
|
||||
table_columns([{t1: ({t1: (t1.a, t1.b)}, {gkey: (t1.b, t1.a)})}]),
|
||||
update([t1.b=column_conv(INT,PS:(11,0),NULL,cast(t1.b + 1, INT(-1, 0)))])
|
||||
1 - output([t1.a], [t1.b]), filter([t1.a > 0]), rowset=16
|
||||
access([t1.a], [t1.b]), partitions(p0)
|
||||
is_index_back=false, is_global_index=true, filter_before_indexback[false],
|
||||
range_key([t1.b], [t1.a]), range(MIN,MIN ; MAX,MAX)always true
|
||||
1 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
2 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
dop=1
|
||||
3 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
force partition granule
|
||||
4 - output([t1.a], [t1.b]), filter(nil), rowset=16
|
||||
access([t1.a], [t1.b]), partitions(p[0-2])
|
||||
is_index_back=false, is_global_index=false,
|
||||
range_key([t1.a]), range(0 ; MAX),
|
||||
range_cond([t1.a > 0])
|
||||
update t1 set b=b+1 where a>0;
|
||||
EXPLAIN BASIC select * from t1;
|
||||
Query Plan
|
||||
|
@ -108,10 +108,6 @@ ObIndexSkylineDim *ObSkylinePrunningTest::create_skyline_index_dim(
|
||||
ObArray<uint64_t> filter_array;
|
||||
to_array(filter_ids, filter_cnt, filter_array);
|
||||
t->add_index_back_dim(index_back,
|
||||
interest_cnt > 0,
|
||||
range_cnt > 0,
|
||||
index_column_cnt,
|
||||
filter_array,
|
||||
allocator_);
|
||||
ObArray<uint64_t> interest_array;
|
||||
ObArray<uint64_t> rowkey_array;
|
||||
@ -161,25 +157,10 @@ void ObSkylinePrunningTest::check_index_back_dim(const bool left_index_back,
|
||||
{
|
||||
ObIndexBackDim left_dim;
|
||||
left_dim.set_index_back(left_index_back);
|
||||
left_dim.set_interesting_order(left_has_interesting_order);
|
||||
left_dim.set_extract_range(left_can_extract_range);
|
||||
left_dim.set_index_column_cnt(left_index_column_cnt);
|
||||
if (left_cnt > 0) {
|
||||
ObArray<uint64_t> left_ids;
|
||||
to_array(left, left_cnt, left_ids);
|
||||
left_dim.add_filter_column_ids(left_ids);
|
||||
}
|
||||
|
||||
ObIndexBackDim right_dim;
|
||||
right_dim.set_index_back(right_index_back);
|
||||
right_dim.set_interesting_order(right_has_interesting_order);
|
||||
right_dim.set_extract_range(right_can_extract_range);
|
||||
right_dim.set_index_column_cnt(right_index_column_cnt);
|
||||
if (right_cnt > 0) {
|
||||
ObArray<uint64_t> right_ids;
|
||||
to_array(right, right_cnt, right_ids);
|
||||
right_dim.add_filter_column_ids(right_ids);
|
||||
}
|
||||
|
||||
check(&left_dim, &right_dim, status, reverse_status);
|
||||
}
|
||||
|
||||
@ -358,8 +339,8 @@ TEST_F(ObSkylinePrunningTest, index_dim)
|
||||
right_index_column_cnt,
|
||||
right_filter_columns,
|
||||
right_filter_column_cnt,
|
||||
ObSkylineDim::UNCOMPARABLE,
|
||||
ObSkylineDim::UNCOMPARABLE);
|
||||
ObSkylineDim::LEFT_DOMINATED,
|
||||
ObSkylineDim::RIGHT_DOMINATED);
|
||||
}
|
||||
|
||||
{
|
||||
@ -442,8 +423,8 @@ TEST_F(ObSkylinePrunningTest, index_dim)
|
||||
right_index_column_cnt,
|
||||
right_filter_columns,
|
||||
right_filter_column_cnt,
|
||||
ObSkylineDim::UNCOMPARABLE,
|
||||
ObSkylineDim::UNCOMPARABLE);
|
||||
ObSkylineDim::LEFT_DOMINATED,
|
||||
ObSkylineDim::RIGHT_DOMINATED);
|
||||
}
|
||||
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user