[CP] refine cost of base table

This commit is contained in:
zzg19950727 2023-11-27 07:28:18 +00:00 committed by ob-robot
parent 4c009c7342
commit e63f6e8dbe
6 changed files with 176 additions and 12 deletions

View File

@ -1756,3 +1756,6 @@ ERRSIM_DEF_STR(palf_inject_receive_log_error_zone, OB_CLUSTER_PARAMETER, "", "sp
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
ERRSIM_DEF_STR(migrate_check_member_list_error_zone, OB_CLUSTER_PARAMETER, "", "specifies the zone name that migrate want to inject error when change member list",
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
DEF_INT(optimizer_index_cost_adj, OB_TENANT_PARAMETER, "0", "[0,100]",
"adjust costing of index scan",
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

View File

@ -5091,7 +5091,7 @@ int AccessPath::assign(const AccessPath &other, common::ObIAllocator *allocator)
// compute auto dop for access path
int AccessPath::compute_parallel_degree(const int64_t cur_min_parallel_degree,
int64_t &parallel) const
int64_t &parallel)
{
int ret = OB_SUCCESS;
parallel = ObGlobalHint::UNSET_PARALLEL;
@ -5275,24 +5275,57 @@ int AccessPath::prepare_estimate_parallel(const int64_t pre_parallel,
int AccessPath::estimate_cost_for_parallel(const int64_t cur_parallel,
const double part_cnt_per_dop,
double &px_cost,
double &cost) const
double &cost)
{
int ret = OB_SUCCESS;
px_cost = 0.0;
cost = 0.0;
double stats_phy_query_range_row_count = 0;
double stats_logical_query_range_row_count = 0;
int64_t opt_stats_cost_percent = 0;
bool adj_cost_is_valid = false;
double storage_est_cost = 0.0;
double stats_est_cost = 0.0;
double storage_est_px_cost = 0.0;
double stats_est_px_cost = 0.0;
double opt_phy_query_range_row_count = est_cost_info_.phy_query_range_row_count_;
double opt_logical_query_range_row_count = est_cost_info_.logical_query_range_row_count_;
if (OB_ISNULL(parent_) || OB_ISNULL(parent_->get_plan())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(parent_), K(ret));
} else if (OB_FAIL(check_adj_index_cost_valid(stats_phy_query_range_row_count,
stats_logical_query_range_row_count,
opt_stats_cost_percent,
adj_cost_is_valid))) {
LOG_WARN("failed to check adj index cost valid", K(ret));
} else {
ObOptimizerContext &opt_ctx = parent_->get_plan()->get_optimizer_context();
if (OB_FAIL(ObOptEstCost::cost_table_for_parallel(est_cost_info_,
cur_parallel,
part_cnt_per_dop,
px_cost,
cost,
storage_est_px_cost,
storage_est_cost,
opt_ctx.get_cost_model_type()))) {
LOG_WARN("failed to calculated cost for parallel", K(ret));
} else { /*do nothing*/ }
} else if (!adj_cost_is_valid) {
cost = storage_est_cost;
px_cost = storage_est_px_cost;
} else if (OB_FALSE_IT(est_cost_info_.phy_query_range_row_count_ = stats_phy_query_range_row_count)) {
} else if (OB_FALSE_IT(est_cost_info_.logical_query_range_row_count_ = stats_logical_query_range_row_count)) {
} else if (OB_FAIL(ObOptEstCost::cost_table_for_parallel(est_cost_info_,
cur_parallel,
part_cnt_per_dop,
stats_est_px_cost,
stats_est_cost,
opt_ctx.get_cost_model_type()))) {
LOG_WARN("failed to calculated cost for parallel", K(ret));
} else {
double rate = opt_stats_cost_percent * 1.0 / 100.0;
cost = storage_est_cost * (1-rate) + stats_est_cost * rate;
px_cost = storage_est_px_cost * (1-rate) + stats_est_px_cost * rate;
est_cost_info_.phy_query_range_row_count_ = opt_phy_query_range_row_count;
est_cost_info_.logical_query_range_row_count_ = opt_logical_query_range_row_count;
}
}
return ret;
}
@ -5300,17 +5333,44 @@ int AccessPath::estimate_cost_for_parallel(const int64_t cur_parallel,
int AccessPath::estimate_cost()
{
int ret = OB_SUCCESS;
double stats_phy_query_range_row_count = 0;
double stats_logical_query_range_row_count = 0;
int64_t opt_stats_cost_percent = 0;
bool adj_cost_is_valid = false;
double storage_est_cost = 0.0;
double stats_est_cost = 0.0;
double opt_phy_query_range_row_count = est_cost_info_.phy_query_range_row_count_;
double opt_logical_query_range_row_count = est_cost_info_.logical_query_range_row_count_;
if (OB_ISNULL(parent_) || OB_ISNULL(parent_->get_plan())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(parent_), K(ret));
} else if (OB_FAIL(check_adj_index_cost_valid(stats_phy_query_range_row_count,
stats_logical_query_range_row_count,
opt_stats_cost_percent,
adj_cost_is_valid))) {
LOG_WARN("failed to check adj index cost valid", K(ret));
} else {
ObOptimizerContext &opt_ctx = parent_->get_plan()->get_optimizer_context();
if (OB_FAIL(ObOptEstCost::cost_table(est_cost_info_,
parallel_,
cost_,
storage_est_cost,
opt_ctx.get_cost_model_type()))) {
LOG_WARN("failed to get index access info", K(ret));
} else { /*do nothing*/ }
} else if (!adj_cost_is_valid) {
cost_ = storage_est_cost;
} else if (OB_FALSE_IT(est_cost_info_.phy_query_range_row_count_ = stats_phy_query_range_row_count)) {
} else if (OB_FALSE_IT(est_cost_info_.logical_query_range_row_count_ = stats_logical_query_range_row_count)) {
} else if (OB_FAIL(ObOptEstCost::cost_table(est_cost_info_,
parallel_,
stats_est_cost,
opt_ctx.get_cost_model_type()))) {
LOG_WARN("failed to get index access info", K(ret));
} else {
double rate = opt_stats_cost_percent * 1.0 / 100.0;
cost_ = storage_est_cost * (1-rate) + stats_est_cost * rate;
est_cost_info_.phy_query_range_row_count_ = opt_phy_query_range_row_count;
est_cost_info_.logical_query_range_row_count_ = opt_logical_query_range_row_count;
}
}
return ret;
}
@ -5320,18 +5380,54 @@ int AccessPath::re_estimate_cost(EstimateCostInfo &param, double &card, double &
int ret = OB_SUCCESS;
card = get_path_output_rows();
ObOptimizerContext *opt_ctx = NULL;
double stats_phy_query_range_row_count = 0;
double stats_logical_query_range_row_count = 0;
int64_t opt_stats_cost_percent = 0;
bool adj_cost_is_valid = false;
double storage_est_cost = 0.0;
double stats_est_cost = 0.0;
double storage_est_card = card;
double stats_est_card = card;
double opt_phy_query_range_row_count = est_cost_info_.phy_query_range_row_count_;
double opt_logical_query_range_row_count = est_cost_info_.logical_query_range_row_count_;
param.need_parallel_ = (ObGlobalHint::UNSET_PARALLEL == param.need_parallel_ || is_match_all())
? parallel_ : param.need_parallel_;
if (OB_ISNULL(parent_) || OB_ISNULL(parent_->get_plan()) ||
OB_ISNULL(opt_ctx = &parent_->get_plan()->get_optimizer_context())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(parent_), K(opt_ctx), K(ret));
} else if (OB_FAIL(check_adj_index_cost_valid(stats_phy_query_range_row_count,
stats_logical_query_range_row_count,
opt_stats_cost_percent,
adj_cost_is_valid))) {
LOG_WARN("failed to check adj index cost valid", K(ret));
} else if (OB_FAIL(re_estimate_cost(param, est_cost_info_, sample_info_,
opt_ctx->get_cost_model_type(),
card, cost))) {
storage_est_card,
storage_est_cost))) {
LOG_WARN("failed to re estimate cost", K(ret));
} else if (param.override_) {
cost_ = cost;
} else if (!adj_cost_is_valid) {
cost = storage_est_cost;
card = storage_est_card;
if (param.override_) {
cost_ = cost;
}
} else if (OB_FALSE_IT(est_cost_info_.phy_query_range_row_count_ = stats_phy_query_range_row_count)) {
} else if (OB_FALSE_IT(est_cost_info_.logical_query_range_row_count_ = stats_logical_query_range_row_count)) {
} else if (OB_FAIL(re_estimate_cost(param, est_cost_info_, sample_info_,
opt_ctx->get_cost_model_type(),
stats_est_card,
stats_est_cost))) {
LOG_WARN("failed to re estimate cost", K(ret));
} else {
double rate = opt_stats_cost_percent * 1.0 / 100.0;
cost = storage_est_cost * (1-rate) + stats_est_cost * rate;
card = storage_est_card * (1-rate) + stats_est_card * rate;
est_cost_info_.phy_query_range_row_count_ = opt_phy_query_range_row_count;
est_cost_info_.logical_query_range_row_count_ = opt_logical_query_range_row_count;
if (param.override_) {
cost_ = cost;
}
}
return ret;
}
@ -5409,6 +5505,51 @@ int AccessPath::re_estimate_cost(const EstimateCostInfo &param,
return ret;
}
int AccessPath::check_adj_index_cost_valid(double &stats_phy_query_range_row_count,
double &stats_logical_query_range_row_count,
int64_t &opt_stats_cost_percent,
bool &is_valid)const
{
int ret = OB_SUCCESS;
ObLogPlan *plan = NULL;
ObOptimizerContext *opt_ctx = NULL;
ObSQLSessionInfo *session_info = NULL;
const OptTableMeta* table_meta = NULL;
bool enable_adj_index_cost = false;
opt_stats_cost_percent = 0;
double selectivity = 0.0;
if (OB_ISNULL(parent_) || OB_ISNULL(plan = parent_->get_plan()) ||
OB_ISNULL(opt_ctx = &plan->get_optimizer_context()) ||
OB_ISNULL(session_info = opt_ctx->get_session_info()) ||
OB_ISNULL(table_meta = plan->get_basic_table_metas().get_table_meta_by_table_id(table_id_))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("get unexpected null", K(plan), K(opt_ctx), K(ret));
} else if (session_info->is_adj_index_cost_enabled(enable_adj_index_cost, opt_stats_cost_percent)) {
LOG_WARN("failed to check adjust scan enabled", K(ret));
} else if (!enable_adj_index_cost || //session disable adjust
est_cost_info_.prefix_filters_.empty() || //not have query range
!est_cost_info_.pushdown_prefix_filters_.empty() || //can not use storage estimate
table_meta->use_default_stat()) { //not have optimzier stats
is_valid = false;
LOG_TRACE("disable adjust index cost", K(enable_adj_index_cost),
K(est_cost_info_.prefix_filters_.empty()),
K(est_cost_info_.pushdown_prefix_filters_.empty()),
K(table_meta->use_default_stat()));
} else if (OB_FAIL(ObOptSelectivity::calculate_selectivity(plan->get_basic_table_metas(),
plan->get_selectivity_ctx(),
est_cost_info_.prefix_filters_,
selectivity,
plan->get_predicate_selectivities()))) {
LOG_WARN("failed to calculate selectivity", K(ret));
} else {
stats_logical_query_range_row_count = get_table_row_count() * selectivity;
stats_phy_query_range_row_count = stats_logical_query_range_row_count;
is_valid = true;
LOG_TRACE("enable adjust index cost, ", K(opt_stats_cost_percent), K(stats_logical_query_range_row_count));
}
return ret;
}
const ObIArray<ObNewRange>& AccessPath::get_query_ranges() const
{
return est_cost_info_.ranges_;

View File

@ -628,7 +628,7 @@ struct EstimateCostInfo {
{ return est_cost_info_; }
ObCostTableScanInfo &get_cost_table_scan_info() { return est_cost_info_; }
int compute_parallel_degree(const int64_t cur_min_parallel_degree,
int64_t &parallel) const;
int64_t &parallel);
int check_and_prepare_estimate_parallel_params(const int64_t cur_min_parallel_degree,
int64_t &px_part_gi_min_part_per_dop,
double &cost_threshold_us,
@ -646,7 +646,7 @@ struct EstimateCostInfo {
int estimate_cost_for_parallel(const int64_t cur_parallel,
const double part_cnt_per_dop,
double &px_cost,
double &cost) const;
double &cost);
virtual int estimate_cost() override;
virtual int re_estimate_cost(EstimateCostInfo &info, double &card, double &cost) override;
static int re_estimate_cost(const EstimateCostInfo &param,
@ -655,6 +655,10 @@ struct EstimateCostInfo {
const ObOptEstCost::MODEL_TYPE model_type,
double &card,
double &cost);
int check_adj_index_cost_valid(double &stats_phy_query_range_row_count,
double &stats_logical_query_range_row_count,
int64_t &opt_stats_cost_percent,
bool &is_valid) const;
inline bool can_use_remote_estimate()
{
return NULL == table_opt_info_ ? false :

View File

@ -535,6 +535,20 @@ bool ObSQLSessionInfo::is_var_assign_use_das_enabled() const
return bret;
}
int ObSQLSessionInfo::is_adj_index_cost_enabled(bool &enabled, int64_t &stats_cost_percent) const
{
int ret = OB_SUCCESS;
enabled = false;
stats_cost_percent = 0;
int64_t tenant_id = get_effective_tenant_id();
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));
if (tenant_config.is_valid()) {
stats_cost_percent = tenant_config->optimizer_index_cost_adj;
enabled = (0 != stats_cost_percent);
}
return ret;
}
void ObSQLSessionInfo::destroy(bool skip_sys_var)
{
if (is_inited_) {

View File

@ -1167,6 +1167,7 @@ public:
bool is_index_skip_scan_enabled() const;
int is_enable_range_extraction_for_not_in(bool &enabled) const;
bool is_var_assign_use_das_enabled() const;
int is_adj_index_cost_enabled(bool &enabled, int64_t &stats_cost_percent) const;
ObSessionDDLInfo &get_ddl_info() { return ddl_info_; }
void set_ddl_info(const ObSessionDDLInfo &ddl_info) { ddl_info_ = ddl_info; }

View File

@ -169,6 +169,7 @@ ob_ratelimit_stat_period
ob_ssl_invited_common_names
ob_startup_mode
open_cursors
optimizer_index_cost_adj
opt_tab_stat_cache_priority
partition_balance_schedule_interval
plan_cache_evict_interval