289 lines
10 KiB
C++
289 lines
10 KiB
C++
/**
|
|
* Copyright (c) 2021 OceanBase
|
|
* OceanBase CE is licensed under Mulan PubL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
|
* You may obtain a copy of Mulan PubL v2 at:
|
|
* http://license.coscl.org.cn/MulanPubL-2.0
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
* See the Mulan PubL v2 for more details.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX SQL_OPT
|
|
#include "ob_stat_define.h"
|
|
|
|
namespace oceanbase
|
|
{
|
|
namespace common
|
|
{
|
|
const int64_t ObColumnStatParam::DEFAULT_HISTOGRAM_BUCKET_NUM = 254;
|
|
|
|
void ObAnalyzeSampleInfo::set_percent(double percent)
|
|
{
|
|
is_sample_ = true;
|
|
sample_type_ = PercentSample;
|
|
sample_value_ = percent;
|
|
}
|
|
|
|
void ObAnalyzeSampleInfo::set_rows(double row_num)
|
|
{
|
|
is_sample_ = true;
|
|
sample_type_ = RowSample;
|
|
sample_value_ = row_num;
|
|
}
|
|
|
|
bool ObColumnStatParam::is_valid_opt_col_type(const ObObjType type)
|
|
{
|
|
bool ret = false;
|
|
// currently, we only support the following type to collect histogram
|
|
ColumnTypeClass type_class = ob_obj_type_class(type);
|
|
if (type_class == ColumnTypeClass::ObIntTC ||
|
|
type_class == ColumnTypeClass::ObUIntTC ||
|
|
type_class == ColumnTypeClass::ObFloatTC ||
|
|
type_class == ColumnTypeClass::ObDoubleTC ||
|
|
type_class == ColumnTypeClass::ObNumberTC ||
|
|
type_class == ColumnTypeClass::ObDateTimeTC ||
|
|
type_class == ColumnTypeClass::ObDateTC ||
|
|
type_class == ColumnTypeClass::ObTimeTC ||
|
|
type_class == ColumnTypeClass::ObYearTC ||
|
|
type_class == ColumnTypeClass::ObStringTC ||
|
|
type_class == ColumnTypeClass::ObRawTC ||
|
|
type_class == ColumnTypeClass::ObOTimestampTC ||
|
|
type_class == ColumnTypeClass::ObBitTC ||
|
|
type_class == ColumnTypeClass::ObEnumSetTC ||
|
|
type_class == ColumnTypeClass::ObIntervalTC ||
|
|
type_class == ColumnTypeClass::ObDecimalIntTC ||
|
|
(lib::is_mysql_mode() && type_class == ColumnTypeClass::ObTextTC)) {
|
|
ret = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool ObColumnStatParam::is_valid_avglen_type(const ObObjType type)
|
|
{
|
|
bool ret = false;
|
|
// currently, we only support the following type to collect avg len
|
|
ColumnTypeClass type_class = ob_obj_type_class(type);
|
|
if (is_valid_opt_col_type(type) ||
|
|
type_class == ColumnTypeClass::ObTextTC ||
|
|
type_class == ColumnTypeClass::ObRowIDTC ||
|
|
type_class == ColumnTypeClass::ObLobTC) {
|
|
ret = true;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool StatTable::operator<(const StatTable &other) const
|
|
{
|
|
return stale_percent_ < other.stale_percent_;
|
|
}
|
|
|
|
int StatTable::assign(const StatTable &other)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
database_id_ = other.database_id_;
|
|
table_id_ = other.table_id_;
|
|
stale_percent_ = other.stale_percent_;
|
|
return partition_stat_infos_.assign(other.partition_stat_infos_);
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* The order to gather tables
|
|
* 1. gather user tables
|
|
* if table is a 'big table', make it at last
|
|
* if table is first time to gather, then gather it at first
|
|
* else, gather them according to the last gather duration
|
|
* 2. gather sys tables
|
|
* so as to user tables
|
|
* @param other
|
|
* @return true
|
|
* @return false
|
|
*/
|
|
bool ObStatTableWrapper::operator<(const ObStatTableWrapper &other) const
|
|
{
|
|
bool bret = true;
|
|
if (this == &other) {
|
|
bret = false;
|
|
} else if (table_type_ == ObStatTableType::ObSysTable && other.table_type_ == ObStatTableType::ObUserTable) {
|
|
bret = false;
|
|
} else if ((table_type_ == ObStatTableType::ObUserTable && other.table_type_ == ObStatTableType::ObUserTable) ||
|
|
(table_type_ == ObStatTableType::ObSysTable && other.table_type_ == ObStatTableType::ObSysTable)) {
|
|
if (is_big_table_ && !other.is_big_table_) {
|
|
bret = false;
|
|
} else if ((is_big_table_ && other.is_big_table_) ||
|
|
(!is_big_table_ && !other.is_big_table_)) {
|
|
if (stat_type_ == other.stat_type_) {
|
|
bret = last_gather_duration_ < other.last_gather_duration_;
|
|
} else if (stat_type_ == ObStatType::ObStale && other.stat_type_ == ObStatType::ObFirstTimeToGather) {
|
|
bret = false;
|
|
}
|
|
}
|
|
}
|
|
return bret;
|
|
}
|
|
|
|
int ObStatTableWrapper::assign(const ObStatTableWrapper &other)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
if (OB_FAIL(stat_table_.assign(other.stat_table_))) {
|
|
LOG_WARN("failed to assign stat table");
|
|
} else {
|
|
table_type_ = other.table_type_;
|
|
stat_type_ = other.stat_type_;
|
|
is_big_table_ = other.is_big_table_;
|
|
last_gather_duration_ = other.last_gather_duration_;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int ObTableStatParam::assign(const ObTableStatParam &other)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
tenant_id_ = other.tenant_id_;
|
|
db_name_ = other.db_name_;
|
|
db_id_ = other.db_id_;
|
|
tab_name_ = other.tab_name_;
|
|
table_id_ = other.table_id_;
|
|
part_level_ = other.part_level_;
|
|
part_name_ = other.part_name_;
|
|
sample_info_.is_sample_ = other.sample_info_.is_sample_;
|
|
sample_info_.is_block_sample_ = other.sample_info_.is_block_sample_;
|
|
sample_info_.sample_type_ = other.sample_info_.sample_type_;
|
|
sample_info_.sample_value_ = other.sample_info_.sample_value_;
|
|
method_opt_ = other.method_opt_;
|
|
degree_ = other.degree_;
|
|
global_stat_param_ = other.global_stat_param_;
|
|
part_stat_param_ = other.part_stat_param_;
|
|
subpart_stat_param_ = other.subpart_stat_param_;
|
|
granularity_ = other.granularity_;
|
|
cascade_ = other.cascade_;
|
|
stat_tab_ = other.stat_tab_;
|
|
stat_id_ = other.stat_id_;
|
|
stat_own_ = other.stat_own_;
|
|
no_invalidate_ = other.no_invalidate_;
|
|
force_ = other.force_;
|
|
is_subpart_name_ = other.is_subpart_name_;
|
|
stat_category_ = other.stat_category_;
|
|
tab_group_ = other.tab_group_;
|
|
stattype_ = other.stattype_;
|
|
need_approx_ndv_ = other.need_approx_ndv_;
|
|
is_index_stat_ = other.is_index_stat_;
|
|
data_table_name_ = other.data_table_name_;
|
|
is_global_index_ = other.is_global_index_;
|
|
global_part_id_ = other.global_part_id_;
|
|
duration_time_ = other.duration_time_;
|
|
global_tablet_id_ = other.global_tablet_id_;
|
|
global_data_part_id_ = other.global_data_part_id_;
|
|
data_table_id_ = other.data_table_id_;
|
|
need_estimate_block_ = other.need_estimate_block_;
|
|
is_temp_table_ = other.is_temp_table_;
|
|
allocator_ = other.allocator_;
|
|
ref_table_type_ = other.ref_table_type_;
|
|
if (OB_FAIL(part_infos_.assign(other.part_infos_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(subpart_infos_.assign(other.subpart_infos_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(approx_part_infos_.assign(other.approx_part_infos_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(column_params_.assign(other.column_params_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(no_regather_partition_ids_.assign(other.no_regather_partition_ids_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(all_part_infos_.assign(other.all_part_infos_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(all_subpart_infos_.assign(other.all_subpart_infos_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(column_group_params_.assign(other.column_group_params_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else {/*do nothing*/}
|
|
return ret;
|
|
}
|
|
|
|
int ObTableStatParam::assign_common_property(const ObTableStatParam &other)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
sample_info_.is_sample_ = other.sample_info_.is_sample_;
|
|
sample_info_.is_block_sample_ = other.sample_info_.is_block_sample_;
|
|
sample_info_.sample_type_ = other.sample_info_.sample_type_;
|
|
sample_info_.sample_value_ = other.sample_info_.sample_value_;
|
|
method_opt_ = other.method_opt_;
|
|
degree_ = other.degree_;
|
|
global_stat_param_ = other.global_stat_param_;
|
|
part_stat_param_ = other.part_stat_param_;
|
|
subpart_stat_param_ = other.subpart_stat_param_;
|
|
granularity_ = other.granularity_;
|
|
cascade_ = other.cascade_;
|
|
stat_tab_ = other.stat_tab_;
|
|
stat_id_ = other.stat_id_;
|
|
stat_own_ = other.stat_own_;
|
|
no_invalidate_ = other.no_invalidate_;
|
|
force_ = other.force_;
|
|
stat_category_ = other.stat_category_;
|
|
stattype_ = other.stattype_;
|
|
need_approx_ndv_ = other.need_approx_ndv_;
|
|
duration_time_ = other.duration_time_;
|
|
allocator_ = other.allocator_;
|
|
return ret;
|
|
}
|
|
|
|
int ObOptStatGatherParam::assign(const ObOptStatGatherParam &other)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
tenant_id_ = other.tenant_id_;
|
|
db_name_ = other.db_name_;
|
|
tab_name_ = other.tab_name_;
|
|
table_id_ = other.table_id_;
|
|
stat_level_ = other.stat_level_;
|
|
need_histogram_ = other.need_histogram_;
|
|
sample_info_.is_sample_ = other.sample_info_.is_sample_;
|
|
sample_info_.is_block_sample_ = other.sample_info_.is_block_sample_;
|
|
sample_info_.sample_type_ = other.sample_info_.sample_type_;
|
|
sample_info_.sample_value_ = other.sample_info_.sample_value_;
|
|
degree_ = other.degree_;
|
|
allocator_ = other.allocator_;
|
|
partition_id_block_map_ = other.partition_id_block_map_;
|
|
gather_start_time_ = other.gather_start_time_;
|
|
stattype_ = other.stattype_;
|
|
is_split_gather_ = other.is_split_gather_;
|
|
max_duration_time_ = other.max_duration_time_;
|
|
need_approx_ndv_ = other.need_approx_ndv_;
|
|
data_table_name_ = other.data_table_name_;
|
|
global_part_id_ = other.global_part_id_;
|
|
gather_vectorize_ = other.gather_vectorize_;
|
|
sepcify_scn_ = other.sepcify_scn_;
|
|
if (OB_FAIL(partition_infos_.assign(other.partition_infos_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else if (OB_FAIL(column_params_.assign(other.column_params_))) {
|
|
LOG_WARN("failed to assign", K(ret));
|
|
} else {/*do nothing*/}
|
|
return ret;
|
|
}
|
|
|
|
bool ObTableStatParam::is_specify_partition_gather() const
|
|
{
|
|
bool is_specify = false;
|
|
if (part_level_ == share::schema::PARTITION_LEVEL_ZERO) {
|
|
//do nothing
|
|
} else if (part_level_ == share::schema::PARTITION_LEVEL_ONE) {
|
|
is_specify = part_infos_.count() != all_part_infos_.count();
|
|
} else if (part_level_ == share::schema::PARTITION_LEVEL_TWO) {
|
|
is_specify = (part_infos_.count() + approx_part_infos_.count() != all_part_infos_.count()) ||
|
|
(subpart_infos_.count() != all_subpart_infos_.count());
|
|
}
|
|
return is_specify;
|
|
}
|
|
|
|
bool ObTableStatParam::is_specify_column_gather() const
|
|
{
|
|
bool is_specify = false;
|
|
for (int64_t i = 0; !is_specify && i < column_params_.count(); ++i) {
|
|
is_specify = column_params_.at(i).is_valid_opt_col() && !column_params_.at(i).need_basic_stat();
|
|
}
|
|
return is_specify;
|
|
}
|
|
|
|
}
|
|
}
|