diff options
author | Igor Babaev <igor@askmonty.org> | 2013-03-30 22:00:04 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-03-30 22:00:04 -0700 |
commit | 78bab7839502e02d6d62b50d99ac9b0637acb4a1 (patch) | |
tree | dd345c47c4d9a55e1061697151b9e6d38b2a5e07 /sql | |
parent | 905549863454647b6070e23b7cf5fc1394f92750 (diff) | |
parent | 9e1ca1053b5e619e1f6c727abdf787dc163ab4e6 (diff) | |
download | mariadb-git-78bab7839502e02d6d62b50d99ac9b0637acb4a1.tar.gz |
Merge
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_statistics.cc | 22 | ||||
-rw-r--r-- | sql/sql_statistics.h | 106 | ||||
-rw-r--r-- | sql/sys_vars.cc | 11 |
4 files changed, 109 insertions, 31 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h index 2844cab9b4e..0cca72d7d1e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -502,6 +502,7 @@ typedef struct system_variables ulong optimizer_use_condition_selectivity; ulong use_stat_tables; ulong histogram_size; + ulong histogram_type; ulong preload_buff_size; ulong profiling_history_size; ulong read_buff_size; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 0f26ca7520a..74ed90cf7a1 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -928,6 +928,9 @@ public: case COLUMN_STAT_HIST_SIZE: stat_field->store(table_field->collected_stats->histogram.get_size()); break; + case COLUMN_STAT_HIST_TYPE: + stat_field->store(table_field->collected_stats->histogram.get_type()); + break; case COLUMN_STAT_HISTOGRAM: const char * col_histogram= (const char *) (table_field->collected_stats->histogram.get_values()); @@ -971,7 +974,7 @@ public: char buff[MAX_FIELD_WIDTH]; String val(buff, sizeof(buff), &my_charset_utf8_bin); - for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HIST_SIZE; i++) + for (uint i= COLUMN_STAT_MIN_VALUE; i <= COLUMN_STAT_HIST_TYPE; i++) { Field *stat_field= stat_table->field[i]; @@ -1007,6 +1010,10 @@ public: case COLUMN_STAT_HIST_SIZE: table_field->read_stats->histogram.set_size(stat_field->val_int()); break; + case COLUMN_STAT_HIST_TYPE: + Histogram_type hist_type= (Histogram_type) (stat_field->val_int()); + table_field->read_stats->histogram.set_type(hist_type); + break; } } } @@ -1238,7 +1245,7 @@ class Histogram_builder Field *min_value; Field *max_value; Histogram *histogram; - uint hist_size; + uint hist_width; double bucket_capacity; uint curr_bucket; ulonglong count; @@ -1252,8 +1259,8 @@ public: min_value= col_stats->min_value; max_value= col_stats->max_value; histogram= &col_stats->histogram; - hist_size= histogram->get_size(); - bucket_capacity= (double) records / (hist_size + 1); + hist_width= histogram->get_width(); + bucket_capacity= (double) records / (hist_width + 1); curr_bucket= 0; count= 0; count_distinct= 0; @@ -1265,7 +1272,7 @@ public: { count_distinct++; count+= elem_cnt; - if (curr_bucket == hist_size) + if (curr_bucket == hist_width) return 0; if (count > bucket_capacity * (curr_bucket + 1)) { @@ -1273,7 +1280,7 @@ public: histogram->set_value(curr_bucket, column->middle_point_pos(min_value, max_value)); curr_bucket++; - while (curr_bucket != hist_size && + while (curr_bucket != hist_width && count > bucket_capacity * (curr_bucket + 1)) { histogram->set_prev_value(curr_bucket); @@ -1794,6 +1801,7 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) columns++; } uint hist_size= thd->variables.histogram_size; + Histogram_type hist_type= (Histogram_type) (thd->variables.histogram_type); uchar *histogram= NULL; if (hist_size > 0) histogram= (uchar *) alloc_root(&table->mem_root, hist_size * columns); @@ -1818,6 +1826,7 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) if (bitmap_is_set(table->read_set, (*field_ptr)->field_index)) { column_stats->histogram.set_size(hist_size); + column_stats->histogram.set_type(hist_type); column_stats->histogram.set_values(histogram); histogram+= hist_size; } @@ -2200,6 +2209,7 @@ void Column_statistics_collected::finish(ha_rows rows) set_not_null(COLUMN_STAT_HIST_SIZE); if (hist_size && distincts) { + set_not_null(COLUMN_STAT_HIST_TYPE); histogram.set_values(count_distinct->get_histogram()); set_not_null(COLUMN_STAT_HISTOGRAM); } diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 9a2b5c2433b..b699ec7100a 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -24,6 +24,13 @@ enum enum_use_stat_tables_mode PEFERABLY, } Use_stat_tables_mode; +typedef +enum enum_histogram_type +{ + SINGLE_PREC_HB, + DOUBLE_PREC_HB +} Histogram_type; + enum enum_stat_tables { TABLE_STAT, @@ -59,6 +66,7 @@ enum enum_column_stat_col COLUMN_STAT_AVG_LENGTH, COLUMN_STAT_AVG_FREQUENCY, COLUMN_STAT_HIST_SIZE, + COLUMN_STAT_HIST_TYPE, COLUMN_STAT_HISTOGRAM }; @@ -99,46 +107,74 @@ double get_column_range_cardinality(Field *field, key_range *min_endp, key_range *max_endp); -#define HIST_FACTOR 255 -#define INV_HIST_FACTOR ((double) 1.0 / HIST_FACTOR) - class Histogram { + private: + Histogram_type type; + uint8 size; + uchar *values; + + uint prec_factor() + { + switch (type) { + case SINGLE_PREC_HB: + return ((uint) (1 << 8) - 1); + case DOUBLE_PREC_HB: + return ((uint) (1 << 16) - 1); + } + } + public: + uint get_width() + { + switch (type) { + case SINGLE_PREC_HB: + return size; + case DOUBLE_PREC_HB: + return size / 2; + } + } private: - uint8 size; - uint8 *values; + uint get_value(uint i) + { + switch (type) { + case SINGLE_PREC_HB: + return (uint) (((uint8 *) values)[i]); + case DOUBLE_PREC_HB: + return (uint) (((uint16 *) values)[i]); + } + } uint find_bucket(double pos, bool first) { - uint8 val= (uint8) (pos * HIST_FACTOR); + uint val= (uint) (pos * prec_factor()); int lp= 0; - int rp= size - 1; - int i= 0; - for (int d= size / 2 ; d; d= (rp - lp) / 2) + int rp= get_width() - 1; + uint i= 0; + for (int d= get_width() / 2 ; d; d= (rp - lp) / 2) { i= lp + d; - if (val == values[i]) + if (val == get_value(i)) break; - if (val < values[i]) + if (val < get_value(i)) rp= i; - else if (val > values[i + 1]) + else if (val > get_value(i + 1)) lp= i + 1; else break; } - if (val == values[i]) + if (val == get_value(i)) { if (first) { - while(i && val == values[i - 1]) + while(i && val == get_value(i - 1)) i--; } else { - while(i + 1 < size && val == values[i + 1]) + while(i + 1 < get_width() && val == get_value(i + 1)) i++; } } @@ -149,24 +185,44 @@ public: uint get_size() { return (uint) size; } + Histogram_type get_type() { return type; } + uchar *get_values() { return (uchar *) values; } void set_size (ulonglong sz) { size= (uint8) sz; } - void set_values (uchar *vals) { values= (uint8 *) vals; } + void set_type (Histogram_type t) { type= t; } + + void set_values (uchar *vals) { values= (uchar *) vals; } void set_value(uint i, double val) { - values[i]= (uint8) (val * HIST_FACTOR); + switch (type) { + case SINGLE_PREC_HB: + ((uint8 *) values)[i]= (uint8) (val * prec_factor()); + return; + case DOUBLE_PREC_HB: + ((uint16 *) values)[i]= (uint16) (val * prec_factor()); + return; + } } - void set_prev_value(uint i) { values[i]= values[i-1]; } - + void set_prev_value(uint i) + { + switch (type) { + case SINGLE_PREC_HB: + ((uint8 *) values)[i]= ((uint8 *) values)[i-1]; + return; + case DOUBLE_PREC_HB: + ((uint16 *) values)[i]= ((uint16 *) values)[i-1]; + return; + } + } double range_selectivity(double min_pos, double max_pos) { double sel; - double bucket_sel= 1.0/(size + 1); + double bucket_sel= 1.0/(get_width() + 1); uint min= find_bucket(min_pos, TRUE); uint max= find_bucket(max_pos, FALSE); sel= bucket_sel * (max - min + 1); @@ -176,14 +232,14 @@ public: double point_selectivity(double pos, double avg_sel) { double sel; - double bucket_sel= 1.0/(size + 1); + double bucket_sel= 1.0/(get_width() + 1); uint min= find_bucket(pos, TRUE); uint max= min; - while (max + 1 < size && values[max + 1] == values[max]) + while (max + 1 < get_width() && get_value(max + 1) == get_value(max)) max++; - double width= ((max + 1 == size ? 1.0 : values[max]) - - (min == 0 ? 0.0 : values[min-1])) * - INV_HIST_FACTOR; + double width= ((max + 1 == get_width() ? 1.0 : get_value(max)) - + (min == 0 ? 0.0 : get_value(min-1))) * + ((double) 1.0 / prec_factor()); sel= avg_sel * (bucket_sel * (max + 1 - min)) / width; return sel; } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 2bf9a55f8b1..aa0c4232466 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3777,6 +3777,17 @@ static Sys_var_ulong Sys_histogram_size( SESSION_VAR(histogram_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 255), DEFAULT(0), BLOCK_SIZE(1)); +const char *histogram_types[] = + {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0}; +static Sys_var_enum Sys_histogram_type( + "histogram_type", + "Specifies type of the histograms created by ANALYZE. " + "Possible values are: " + "SINGLE_PREC_HB - single precision height-balanced, " + "DOUBLE_PREC_HB - double precision height-balanced.", + SESSION_VAR(histogram_type), CMD_LINE(REQUIRED_ARG), + histogram_types, DEFAULT(0)); + static Sys_var_mybool Sys_no_thread_alarm( "debug_no_thread_alarm", "Disable system thread alarm calls. Disabling it may be useful " |