[FEAT MERGE] implement dynamic sampling
This commit is contained in:
@ -69,9 +69,12 @@ int OptTableMeta::assign(const OptTableMeta &other)
|
||||
ref_table_id_ = other.ref_table_id_;
|
||||
rows_ = other.rows_;
|
||||
stat_type_ = other.stat_type_;
|
||||
ds_level_ = other.ds_level_;
|
||||
|
||||
if (OB_FAIL(all_used_parts_.assign(other.all_used_parts_))) {
|
||||
LOG_WARN("failed to assign all used parts", K(ret));
|
||||
} else if (OB_FAIL(all_used_tablets_.assign(other.all_used_tablets_))) {
|
||||
LOG_WARN("failed to assign all used tablets", K(ret));
|
||||
} else if (OB_FAIL(column_metas_.assign(other.column_metas_))) {
|
||||
LOG_WARN("failed to assign all csata", K(ret));
|
||||
} else if (OB_FAIL(pk_ids_.assign(other.pk_ids_))) {
|
||||
@ -87,6 +90,7 @@ int OptTableMeta::init(const uint64_t table_id,
|
||||
const int64_t stat_type,
|
||||
ObSqlSchemaGuard &schema_guard,
|
||||
ObIArray<int64_t> &all_used_part_id,
|
||||
common::ObIArray<ObTabletID> &all_used_tablets,
|
||||
ObIArray<uint64_t> &column_ids,
|
||||
const OptSelectivityCtx &ctx)
|
||||
{
|
||||
@ -101,6 +105,8 @@ int OptTableMeta::init(const uint64_t table_id,
|
||||
stat_type_ = stat_type;
|
||||
if (OB_FAIL(all_used_parts_.assign(all_used_part_id))) {
|
||||
LOG_WARN("failed to assign all used partition ids", K(ret));
|
||||
} else if (OB_FAIL(all_used_tablets_.assign(all_used_tablets))) {
|
||||
LOG_WARN("failed to assign all used partition ids", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_table_schema(table_id_, ref_table_id_, ctx.get_stmt(), table_schema))) {
|
||||
LOG_WARN("failed to get table schmea", K(ret), K(ref_table_id_));
|
||||
} else if (OB_ISNULL(table_schema)) {
|
||||
@ -205,6 +211,7 @@ int OptTableMetas::add_base_table_meta_info(OptSelectivityCtx &ctx,
|
||||
const uint64_t ref_table_id,
|
||||
const int64_t rows,
|
||||
ObIArray<int64_t> &all_used_part_id,
|
||||
ObIArray<ObTabletID> &all_used_tablets,
|
||||
ObIArray<uint64_t> &column_ids,
|
||||
const int64_t stat_type,
|
||||
int64_t last_analyzed)
|
||||
@ -219,7 +226,8 @@ int OptTableMetas::add_base_table_meta_info(OptSelectivityCtx &ctx,
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to allocate place holder for table meta", K(ret));
|
||||
} else if (OB_FAIL(table_meta->init(table_id, ref_table_id, rows, stat_type,
|
||||
*schema_guard, all_used_part_id, column_ids, ctx))) {
|
||||
*schema_guard, all_used_part_id, all_used_tablets,
|
||||
column_ids, ctx))) {
|
||||
LOG_WARN("failed to init new tstat", K(ret));
|
||||
} else {
|
||||
table_meta->set_version(last_analyzed);
|
||||
@ -481,11 +489,17 @@ int ObOptSelectivity::calculate_selectivity(const OptTableMetas &table_metas,
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
selectivity = 1.0;
|
||||
bool is_calculated = false;
|
||||
ObSEArray<ObRawExpr *, 4> join_conditions;
|
||||
ObSEArray<RangeExprs, 3> range_conditions;
|
||||
ObRawExpr *qual = NULL;
|
||||
double tmp_selectivity = 1.0;
|
||||
bool need_skip = false;
|
||||
//we calc some complex predicates selectivity by dynamic sampling
|
||||
if (OB_FAIL(calc_complex_predicates_selectivity_by_ds(table_metas, ctx, predicates,
|
||||
all_predicate_sel))) {
|
||||
LOG_WARN("failed to calc complex predicates selectivity by ds", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < predicates.count(); ++i) {
|
||||
qual = predicates.at(i);
|
||||
LOG_TRACE("calculate qual selectivity", "expr", PNAME(qual));
|
||||
@ -555,6 +569,249 @@ int ObOptSelectivity::calculate_selectivity(const OptTableMetas &table_metas,
|
||||
return ret;
|
||||
}
|
||||
|
||||
//try to calc complex predicate selectivity by dynamic sampling
|
||||
int ObOptSelectivity::calc_complex_predicates_selectivity_by_ds(const OptTableMetas &table_metas,
|
||||
const OptSelectivityCtx &ctx,
|
||||
const ObIArray<ObRawExpr*> &predicates,
|
||||
ObIArray<ObExprSelPair> &all_predicate_sel)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<OptSelectivityDSParam, 4> ds_params;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < predicates.count(); ++i) {
|
||||
if (OB_FAIL(resursive_extract_valid_predicate_for_ds(table_metas, ctx, predicates.at(i), ds_params))) {
|
||||
LOG_WARN("failed to resursive extract valid predicate for ds", K(ret));
|
||||
} else {/*do nothing*/}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < ds_params.count(); ++i) {
|
||||
if (OB_FAIL(calc_selectivity_by_dynamic_sampling(ctx, ds_params.at(i), all_predicate_sel))) {
|
||||
LOG_WARN("failed to calc selectivity by dynamic sampling", K(ret));
|
||||
} else {/*do nothing*/}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptSelectivity::calc_selectivity_by_dynamic_sampling(const OptSelectivityCtx &ctx,
|
||||
const OptSelectivityDSParam &ds_param,
|
||||
ObIArray<ObExprSelPair> &all_predicate_sel)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LOG_TRACE("begin to calc selectivity by dynamic sampling", K(ds_param));
|
||||
OPT_TRACE("begin to process filter dynamic sampling estimation");
|
||||
ObDSTableParam ds_table_param;
|
||||
ObSEArray<ObDSResultItem, 4> ds_result_items;
|
||||
bool specify_ds = false;
|
||||
if (OB_FAIL(ObDynamicSamplingUtils::get_ds_table_param(const_cast<ObOptimizerContext &>(ctx.get_opt_ctx()),
|
||||
ctx.get_plan(),
|
||||
ds_param.table_meta_,
|
||||
true,
|
||||
ds_table_param,
|
||||
specify_ds))) {
|
||||
LOG_WARN("failed to get ds table param", K(ret), K(ds_table_param));
|
||||
} else if (!ds_table_param.is_valid()) {
|
||||
//do nothing
|
||||
} else if (OB_FAIL(add_ds_result_items(ds_param.quals_,
|
||||
ds_param.table_meta_->get_ref_table_id(),
|
||||
ds_result_items))) {
|
||||
LOG_WARN("failed to init ds result items", K(ret));
|
||||
} else {
|
||||
ObArenaAllocator allocator("ObOpTableDS", OB_MALLOC_NORMAL_BLOCK_SIZE, ctx.get_session_info()->get_effective_tenant_id());
|
||||
ObDynamicSampling dynamic_sampling(const_cast<ObOptimizerContext &>(ctx.get_opt_ctx()), allocator);
|
||||
int64_t start_time = ObTimeUtility::current_time();
|
||||
bool throw_ds_error = false;
|
||||
if (OB_FAIL(dynamic_sampling.estimate_table_rowcount(ds_table_param, ds_result_items, throw_ds_error))) {
|
||||
if (!throw_ds_error) {
|
||||
LOG_WARN("failed to estimate filter rowcount caused by some reason, please check!!!", K(ret),
|
||||
K(start_time), K(ObTimeUtility::current_time() - start_time), K(ds_table_param),
|
||||
K(ctx.get_session_info()->get_current_query_string()));
|
||||
if (OB_FAIL(ObDynamicSamplingUtils::add_failed_ds_table_list(ds_param.table_meta_->get_ref_table_id(),
|
||||
ds_param.table_meta_->get_all_used_parts(),
|
||||
const_cast<ObOptimizerContext &>(ctx.get_opt_ctx()).get_failed_ds_tab_list()))) {
|
||||
LOG_WARN("failed to add failed ds table list", K(ret));
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("failed to dynamic sampling", K(ret), K(start_time), K(ds_table_param));
|
||||
}
|
||||
} else if (OB_FAIL(add_ds_result_into_selectivity(ds_result_items,
|
||||
ds_param.table_meta_->get_ref_table_id(),
|
||||
all_predicate_sel))) {
|
||||
LOG_WARN("failed to add ds result into selectivity", K(ret));
|
||||
} else {
|
||||
const_cast<OptTableMeta *>(ds_param.table_meta_)->set_ds_level(ds_table_param.ds_level_);
|
||||
}
|
||||
}
|
||||
OPT_TRACE("end to process filter dynamic sampling estimation");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptSelectivity::add_ds_result_into_selectivity(const ObIArray<ObDSResultItem> &ds_result_items,
|
||||
const uint64_t ref_table_id,
|
||||
ObIArray<ObExprSelPair> &all_predicate_sel)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDSResultItem *basic_item = NULL;
|
||||
if (OB_ISNULL(basic_item = ObDynamicSamplingUtils::get_ds_result_item(ObDSResultItemType::OB_DS_BASIC_STAT,
|
||||
ref_table_id,
|
||||
ds_result_items)) ||
|
||||
OB_ISNULL(basic_item->stat_handle_.stat_) ||
|
||||
OB_UNLIKELY(basic_item->stat_handle_.stat_->get_sample_block_ratio() <= 0 ||
|
||||
basic_item->stat_handle_.stat_->get_sample_block_ratio() > 100.0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(basic_item), K(ds_result_items));
|
||||
} else if (basic_item->stat_handle_.stat_->get_rowcount() == 0 &&
|
||||
basic_item->stat_handle_.stat_->get_sample_block_ratio() != 100.0) {
|
||||
//do nothing
|
||||
} else {
|
||||
int64_t rowcount = basic_item->stat_handle_.stat_->get_rowcount();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < ds_result_items.count(); ++i) {
|
||||
if (ds_result_items.at(i).type_ == ObDSResultItemType::OB_DS_FILTER_OUTPUT_STAT) {
|
||||
if (OB_ISNULL(ds_result_items.at(i).stat_handle_.stat_) ||
|
||||
OB_UNLIKELY(ds_result_items.at(i).exprs_.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected null", K(ret), K(basic_item), K(ds_result_items));
|
||||
} else {
|
||||
int64_t filter_row_count = ds_result_items.at(i).stat_handle_.stat_->get_rowcount();
|
||||
double sample_ratio = ds_result_items.at(i).stat_handle_.stat_->get_sample_block_ratio();
|
||||
filter_row_count = filter_row_count != 0 ? filter_row_count : static_cast<int64_t>(100.0 / sample_ratio);
|
||||
double selectivity = 1.0 * filter_row_count / rowcount;
|
||||
if (OB_FAIL(add_var_to_array_no_dup(all_predicate_sel, ObExprSelPair(ds_result_items.at(i).exprs_.at(0), selectivity)))) {
|
||||
LOG_WARN("failed to add selectivity to plan", K(ret), K(ds_result_items.at(i).exprs_.at(0)), K(selectivity));
|
||||
} else {
|
||||
LOG_TRACE("Succeed to add ds result into selectivity", K(ds_result_items.at(i)), K(selectivity), K(rowcount));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptSelectivity::add_ds_result_items(const ObIArray<ObRawExpr*> &quals,
|
||||
const uint64_t ref_table_id,
|
||||
ObIArray<ObDSResultItem> &ds_result_items)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
//add rowcount
|
||||
ObDSResultItem basic_item(ObDSResultItemType::OB_DS_BASIC_STAT, ref_table_id);
|
||||
if (OB_FAIL(ds_result_items.push_back(basic_item))) {
|
||||
LOG_WARN("failed to push back", K(ret));
|
||||
}
|
||||
//add filter
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < quals.count(); ++i) {
|
||||
ObDSResultItem tmp_item(ObDSResultItemType::OB_DS_FILTER_OUTPUT_STAT, ref_table_id);
|
||||
if (OB_FAIL(tmp_item.exprs_.push_back(quals.at(i)))) {
|
||||
LOG_WARN("failed to assign", K(ret));
|
||||
} else if (OB_FAIL(ds_result_items.push_back(tmp_item))) {
|
||||
LOG_WARN("failed to push back", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptSelectivity::resursive_extract_valid_predicate_for_ds(const OptTableMetas &table_metas,
|
||||
const OptSelectivityCtx &ctx,
|
||||
const ObRawExpr *qual,
|
||||
ObIArray<OptSelectivityDSParam> &ds_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(qual)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected error", K(ret));
|
||||
} else if (qual->get_relation_ids().num_members() == 1) {//single table filter
|
||||
if (qual->has_flag(CNT_DYNAMIC_PARAM) ||
|
||||
qual->has_flag(CNT_SUB_QUERY)) {//can't do dynamic sampling
|
||||
//do nothing
|
||||
} else if (qual->has_flag(CNT_AGG) ||
|
||||
qual->is_const_expr() ||
|
||||
qual->is_column_ref_expr() ||
|
||||
T_OP_EQ == qual->get_expr_type() ||
|
||||
T_OP_NSEQ == qual->get_expr_type() ||
|
||||
T_OP_IN == qual->get_expr_type() ||
|
||||
T_OP_NOT_IN == qual->get_expr_type() ||
|
||||
T_OP_IS == qual->get_expr_type() ||
|
||||
T_OP_IS_NOT == qual->get_expr_type() ||
|
||||
IS_RANGE_CMP_OP(qual->get_expr_type()) ||
|
||||
T_OP_BTW == qual->get_expr_type() ||
|
||||
T_OP_NOT_BTW == qual->get_expr_type() ||
|
||||
T_OP_NE == qual->get_expr_type()) {
|
||||
//here we can try use selectivity calc formula by opt stats, and we don't use dynmaic sampling.
|
||||
} else if (T_OP_NOT == qual->get_expr_type() ||
|
||||
T_OP_AND == qual->get_expr_type() ||
|
||||
T_OP_OR == qual->get_expr_type()) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < qual->get_param_count(); ++i) {
|
||||
if (OB_FAIL(SMART_CALL(resursive_extract_valid_predicate_for_ds(table_metas,
|
||||
ctx,
|
||||
qual->get_param_expr(i),
|
||||
ds_params)))) {
|
||||
LOG_WARN("failed to resursive extract valid predicate for ds", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (T_OP_LIKE == qual->get_expr_type()) {
|
||||
bool can_calc_sel = false;
|
||||
double selectivity = 1.0;
|
||||
if (OB_FAIL(get_like_sel(table_metas, ctx, *qual, selectivity, can_calc_sel))) {
|
||||
LOG_WARN("failed to get like selectivity", K(ret));
|
||||
} else if (can_calc_sel) {
|
||||
//do nothing
|
||||
} else if (OB_FAIL(add_valid_ds_qual(qual, table_metas, ds_params))) {
|
||||
LOG_WARN("failed to add valid ds qual", K(ret));
|
||||
}
|
||||
//filter can't use selectivity calc formula, such as :lnnvl, regexp, not like and so on.
|
||||
} else if (OB_FAIL(add_valid_ds_qual(qual, table_metas, ds_params))) {
|
||||
LOG_WARN("failed to add valid ds qual", K(ret));
|
||||
} else {/*do nothing*/}
|
||||
} else {/*do nothing*/}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptSelectivity::add_valid_ds_qual(const ObRawExpr *qual,
|
||||
const OptTableMetas &table_metas,
|
||||
ObIArray<OptSelectivityDSParam> &ds_params)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<uint64_t, 8> table_ids;
|
||||
ObSEArray<ObRawExpr *, 1> quals;
|
||||
bool no_use = false;
|
||||
if (OB_FAIL(quals.push_back(const_cast<ObRawExpr*>(qual)))) {
|
||||
LOG_WARN("failed to push back", K(ret));
|
||||
} else if (OB_FAIL(ObDynamicSamplingUtils::check_ds_can_use_filters(quals, no_use))) {
|
||||
LOG_WARN("failed to check ds can use filters", K(ret));
|
||||
} else if (no_use) {
|
||||
//do nothing
|
||||
} else if (OB_FAIL(ObRawExprUtils::extract_table_ids(qual, table_ids))) {
|
||||
LOG_WARN("failed to extract table ids", K(ret));
|
||||
} else if (OB_UNLIKELY(table_ids.count() != 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected error", K(ret), K(table_ids), KPC(qual));
|
||||
} else {
|
||||
const OptTableMeta *table_meta = table_metas.get_table_meta_by_table_id(table_ids.at(0));
|
||||
if (OB_ISNULL(table_meta) || OB_INVALID_ID == table_meta->get_ref_table_id() ||
|
||||
!table_meta->use_opt_stat()) {
|
||||
// do nothing
|
||||
} else {
|
||||
bool found_it = false;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && !found_it && i < ds_params.count(); ++i) {
|
||||
if (ds_params.at(i).table_meta_ == table_meta) {
|
||||
found_it = true;
|
||||
if (OB_FAIL(add_var_to_array_no_dup(ds_params.at(i).quals_, const_cast<ObRawExpr*>(qual)))) {
|
||||
LOG_WARN("failed to add var to array no dup", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !found_it) {
|
||||
OptSelectivityDSParam ds_param;
|
||||
ds_param.table_meta_ = table_meta;
|
||||
if (OB_FAIL(ds_param.quals_.push_back(const_cast<ObRawExpr*>(qual)))) {
|
||||
LOG_WARN("failed to push back", K(ret));
|
||||
} else if (OB_FAIL(ds_params.push_back(ds_param))) {
|
||||
LOG_WARN("failed to push back", K(ret));
|
||||
}
|
||||
}
|
||||
LOG_TRACE("succeed to add valid ds qual", K(ds_params));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOptSelectivity::check_qual_later_calculation(const OptTableMetas &table_metas,
|
||||
const OptSelectivityCtx &ctx,
|
||||
ObRawExpr &qual,
|
||||
@ -634,6 +891,8 @@ int ObOptSelectivity::calculate_qual_selectivity(const OptTableMetas &table_meta
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
selectivity = 1.0;
|
||||
double tmp_sel = 1.0;
|
||||
int64_t idx = 0;
|
||||
if (qual.has_flag(CNT_AGG)) {
|
||||
if (OB_FAIL(get_agg_sel(table_metas, ctx, qual, selectivity))) {
|
||||
LOG_WARN("failed to get agg expr selectivity", K(ret), K(qual));
|
||||
@ -663,8 +922,13 @@ int ObOptSelectivity::calculate_qual_selectivity(const OptTableMetas &table_meta
|
||||
LOG_WARN("failed to get range cmp selectivity", K(ret));
|
||||
}
|
||||
} else if (T_OP_LIKE == qual.get_expr_type()) {
|
||||
if (OB_FAIL(get_like_sel(table_metas, ctx, qual, selectivity))) {
|
||||
bool can_calc_sel = false;
|
||||
if (OB_FAIL(get_like_sel(table_metas, ctx, qual, selectivity, can_calc_sel))) {
|
||||
LOG_WARN("failed to get like selectivity", K(ret));
|
||||
} else if (can_calc_sel) {//do nothing
|
||||
//try find the calc sel from dynamic sampling
|
||||
} else if (ObOptimizerUtil::find_item(all_predicate_sel, ObExprSelPair(&qual, 0), &idx)) {
|
||||
selectivity = all_predicate_sel.at(idx).sel_;
|
||||
}
|
||||
} else if (T_OP_BTW == qual.get_expr_type() || T_OP_NOT_BTW == qual.get_expr_type()) {
|
||||
if (OB_FAIL(get_btw_sel(table_metas, ctx, qual, selectivity))) {
|
||||
@ -716,6 +980,8 @@ int ObOptSelectivity::calculate_qual_selectivity(const OptTableMetas &table_meta
|
||||
}
|
||||
} else if (qual.is_spatial_expr()) {
|
||||
selectivity = DEFAULT_SPATIAL_SEL;
|
||||
} else if (ObOptimizerUtil::find_item(all_predicate_sel, ObExprSelPair(&qual, 0), &idx)) {
|
||||
selectivity = all_predicate_sel.at(idx).sel_;
|
||||
} else { //任何处理不了的表达式,都认为是0.5的选择率 } else { //任何处理不了的表达式,都认为是0.5的选择率
|
||||
selectivity = DEFAULT_SEL;
|
||||
}
|
||||
@ -2238,7 +2504,8 @@ double ObOptSelectivity::revise_range_sel(double selectivity,
|
||||
int ObOptSelectivity::get_like_sel(const OptTableMetas &table_metas,
|
||||
const OptSelectivityCtx &ctx,
|
||||
const ObRawExpr &qual,
|
||||
double &selectivity)
|
||||
double &selectivity,
|
||||
bool &can_calc_sel)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
selectivity = DEFAULT_INEQ_SEL;
|
||||
@ -2246,6 +2513,7 @@ int ObOptSelectivity::get_like_sel(const OptTableMetas &table_metas,
|
||||
const ObRawExpr *pattern = NULL;
|
||||
const ObRawExpr *escape = NULL;
|
||||
const ParamStore *params = ctx.get_params();
|
||||
can_calc_sel = false;
|
||||
if (3 != qual.get_param_count()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("like expr should have 3 param", K(ret), K(qual));
|
||||
@ -2275,6 +2543,8 @@ int ObOptSelectivity::get_like_sel(const OptTableMetas &table_metas,
|
||||
static_cast<const ObColumnRefRawExpr&>(*variable),
|
||||
qual, selectivity))) {
|
||||
LOG_WARN("Failed to get column range selectivity", K(ret));
|
||||
} else {
|
||||
can_calc_sel = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -3956,8 +4226,7 @@ int ObOptSelectivity::classify_quals(const ObIArray<ObRawExpr*> &quals,
|
||||
sel_info->equal_count_ = std::min(sel_info->equal_count_, temp_equal_count);
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("qual selectivity not find", K(ret));
|
||||
//do nothing, maybe from dynamic sampling.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4112,5 +4381,115 @@ int ObOptSelectivity::convert_valid_obj_for_opt_stats(const ObObj *old_obj,
|
||||
return ret;
|
||||
}
|
||||
|
||||
//will useful in dynamic sampling join in the future
|
||||
// int ObOptSelectivity::calculate_join_selectivity_by_dynamic_sampling(const OptTableMetas &table_metas,
|
||||
// const OptSelectivityCtx &ctx,
|
||||
// const ObIArray<ObRawExpr*> &predicates,
|
||||
// double &selectivity,
|
||||
// bool &is_calculated)
|
||||
// {
|
||||
// int ret = OB_SUCCESS;
|
||||
// ObOptDSJoinParam ds_join_param;
|
||||
// is_calculated = false;
|
||||
// if (OB_FAIL(collect_ds_join_param(table_metas, ctx, predicates, ds_join_param))) {
|
||||
// LOG_WARN("failed to collect ds join param", K(ret));
|
||||
// } else if (ds_join_param.is_valid()) {
|
||||
// ObArenaAllocator allocator("ObOpJoinDS", OB_MALLOC_NORMAL_BLOCK_SIZE, ctx.get_opt_ctx().get_session_info()->get_effective_tenant_id());
|
||||
// ObDynamicSampling dynamic_sampling(const_cast<ObOptimizerContext&>(ctx.get_opt_ctx()),
|
||||
// allocator,
|
||||
// ObDynamicSamplingType::OB_JOIN_DS);
|
||||
// uint64_t join_output_cnt = 0;
|
||||
// int64_t start_time = ObTimeUtility::current_time();
|
||||
// OPT_TRACE("begin to process join dynamic sampling estimation");
|
||||
// int tmp_ret = dynamic_sampling.estimate_join_rowcount(ds_join_param, join_output_cnt);
|
||||
// OPT_TRACE("end to process join dynamic sampling estimation", static_cast<int64_t>(tmp_ret), join_output_cnt);
|
||||
// if (OB_FAIL(tmp_ret)) {
|
||||
// if (tmp_ret == OB_TIMEOUT) {
|
||||
// LOG_INFO("failed to estimate join rowcount caused by timeout", K(start_time),
|
||||
// K(ObTimeUtility::current_time()), K(ds_join_param));
|
||||
// } else {
|
||||
// ret = tmp_ret;
|
||||
// LOG_WARN("failed to estimate join rowcount by dynamic sampling", K(ret));
|
||||
// }
|
||||
// } else if (OB_UNLIKELY(join_output_cnt != 0 &&
|
||||
// ctx.get_row_count_1() * ctx.get_row_count_2() == 0)) {
|
||||
// ret = OB_ERR_UNEXPECTED;
|
||||
// LOG_WARN("get unexpected error", K(ret), K(ctx.get_row_count_1()), K(ctx.get_row_count_2()));
|
||||
// } else {
|
||||
// selectivity = join_output_cnt == 0 ? 0 : revise_between_0_1(join_output_cnt / (ctx.get_row_count_1() * ctx.get_row_count_2()));
|
||||
// is_calculated = true;
|
||||
// LOG_TRACE("succeed to calculate join selectivity by dynamic sampling", K(selectivity),
|
||||
// K(join_output_cnt), K(ctx.get_row_count_1()),
|
||||
// K(ctx.get_row_count_2()), K(ds_join_param));
|
||||
// }
|
||||
// }
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
//maybe we can use basic table dynamic sampling info for join.
|
||||
// int ObOptSelectivity::collect_ds_join_param(const OptTableMetas &table_metas,
|
||||
// const OptSelectivityCtx &ctx,
|
||||
// const ObIArray<ObRawExpr*> &predicates,
|
||||
// ObOptDSJoinParam &ds_join_param)
|
||||
// {
|
||||
// int ret = OB_SUCCESS;
|
||||
// ObSEArray<uint64_t, 2> table_ids;
|
||||
// const ObDMLStmt *stmt = ctx.get_stmt();
|
||||
// bool no_use = false;
|
||||
// ObSEArray<ObRawExpr*, 4> tmp_raw_exprs;
|
||||
// if (OB_ISNULL(stmt)) {
|
||||
// ret = OB_ERR_UNEXPECTED;
|
||||
// LOG_WARN("get unexpected null", K(ret), K(stmt));
|
||||
// } else if (ctx.get_join_type() != INNER_JOIN &&
|
||||
// ctx.get_join_type() != LEFT_OUTER_JOIN &&
|
||||
// ctx.get_join_type() != RIGHT_OUTER_JOIN &&
|
||||
// ctx.get_join_type() != FULL_OUTER_JOIN) {
|
||||
// //now dynamic sampling just for inner join and outer join
|
||||
// } else if (ObAccessPathEstimation::check_ds_can_use_filters(predicates, tmp_raw_exprs, no_use)) {
|
||||
// LOG_WARN("failed to check ds can use filters", K(ret));
|
||||
// } else if (no_use || predicates.empty()) {
|
||||
// //do nothing
|
||||
// } else if (OB_FAIL(ObRawExprUtils::extract_table_ids_from_exprs(predicates, table_ids))) {
|
||||
// LOG_WARN("failed to extract table ids from exprs", K(ret));
|
||||
// } else if (OB_UNLIKELY(table_ids.count() != 2)) {
|
||||
// //do nothing, just skip.
|
||||
// LOG_TRACE("get unexpected table cnt from join conditicons, can't use join dynamic sampling",
|
||||
// K(table_ids), K(table_metas), K(predicates));
|
||||
// // } else if (OB_FAIL(ObAccessPathEstimation::get_dynamic_sampling_max_timeout(ctx.get_opt_ctx(),
|
||||
// // ds_join_param.max_ds_timeout_))) {
|
||||
// // LOG_WARN("failed to get dynamic sampling max timeout", K(ret));
|
||||
// } else {
|
||||
// bool succ_to_get_param = true;
|
||||
// ds_join_param.join_type_ = ctx.get_join_type();
|
||||
// ds_join_param.join_conditions_ = &predicates;
|
||||
// ds_join_param.max_ds_timeout_ = ctx.get_opt_ctx().get_max_ds_timeout();
|
||||
// for (int64_t i = 0; OB_SUCC(ret) && succ_to_get_param && i < table_ids.count(); ++i) {
|
||||
// ObOptDSBaseParam &base_param = (i == 0 ? ds_join_param.left_table_param_ :
|
||||
// ds_join_param.right_table_param_);
|
||||
// const OptTableMeta *table_meta = table_metas.get_table_meta_by_table_id(table_ids.at(i));
|
||||
// const TableItem *table_item = stmt->get_table_item_by_id(table_ids.at(i));
|
||||
// if (OB_ISNULL(table_meta) || OB_ISNULL(table_item) ||
|
||||
// OB_UNLIKELY(OB_INVALID_ID == table_meta->get_ref_table_id())) {
|
||||
// succ_to_get_param = false;
|
||||
// LOG_TRACE("get invalid table info, can't use dynamic sampling", KPC(table_meta),
|
||||
// KPC(table_item));
|
||||
// } else if (table_meta->get_ds_base_param().is_valid()) {
|
||||
// if (table_meta->get_ds_base_param().ds_level_ != ObDynamicSamplingLevel::ADS_DYNAMIC_SAMPLING) {
|
||||
// succ_to_get_param = false;
|
||||
// } else if (OB_FAIL(base_param.assign(table_meta->get_ds_base_param()))) {
|
||||
// LOG_WARN("failed to assign", K(ret));
|
||||
// } else {
|
||||
// base_param.index_id_ = table_meta->get_ref_table_id();//reset the index id
|
||||
// LOG_TRACE("succed get base param for join dynamic sampling", K(base_param));
|
||||
// }
|
||||
// } else {
|
||||
// succ_to_get_param = false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
|
||||
}//end of namespace sql
|
||||
}//end of namespace oceanbase
|
||||
|
||||
Reference in New Issue
Block a user