diff options
| author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-12 10:48:53 +0200 |
|---|---|---|
| committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-12 10:48:53 +0200 |
| commit | f77f8f6d1a5f4846766a8aab00a9e1e5f41909a1 (patch) | |
| tree | 96a2c880e1756bba3e7350cd2adfd404d176d002 /sql | |
| parent | ecd3a7e00de28d279ef180e1d4defa979e80f9e4 (diff) | |
| parent | d956709b4be67f96a869d0854c75d10cd502172b (diff) | |
| download | mariadb-git-f77f8f6d1a5f4846766a8aab00a9e1e5f41909a1.tar.gz | |
Merge 10.0 into 10.1
Diffstat (limited to 'sql')
| -rw-r--r-- | sql/opt_range.cc | 19 | ||||
| -rw-r--r-- | sql/partition_info.cc | 17 | ||||
| -rw-r--r-- | sql/partition_info.h | 1 | ||||
| -rw-r--r-- | sql/sql_statistics.cc | 45 | ||||
| -rw-r--r-- | sql/sql_statistics.h | 1 |
5 files changed, 74 insertions, 9 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index f3740a08fc6..41d74611abc 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2734,14 +2734,17 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, { Field **field_ptr; TABLE *table= param->table; + partition_info *part_info= NULL; + #ifdef WITH_PARTITION_STORAGE_ENGINE + part_info= table->part_info; + #endif uint parts= 0; for (field_ptr= table->field; *field_ptr; field_ptr++) { - Column_statistics* col_stats= (*field_ptr)->read_stats; - if (bitmap_is_set(used_fields, (*field_ptr)->field_index) - && col_stats && !col_stats->no_stat_values_provided() - && !((*field_ptr)->type() == MYSQL_TYPE_GEOMETRY)) + Field *field= *field_ptr; + if (bitmap_is_set(used_fields, field->field_index) && + is_eits_usable(field)) parts++; } @@ -2759,12 +2762,10 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param, uint max_key_len= 0; for (field_ptr= table->field; *field_ptr; field_ptr++) { - if (bitmap_is_set(used_fields, (*field_ptr)->field_index)) + Field *field= *field_ptr; + if (bitmap_is_set(used_fields, field->field_index)) { - Field *field= *field_ptr; - Column_statistics* col_stats= field->read_stats; - if (field->type() == MYSQL_TYPE_GEOMETRY || - !col_stats || col_stats->no_stat_values_provided()) + if (!is_eits_usable(field)) continue; uint16 store_length; diff --git a/sql/partition_info.cc b/sql/partition_info.cc index df0a733f121..74a1c2a267a 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -3143,6 +3143,23 @@ void partition_info::print_debug(const char *str, uint *value) DBUG_PRINT("info", ("parser: %s", str)); DBUG_VOID_RETURN; } + +bool partition_info::field_in_partition_expr(Field *field) const +{ + uint i; + for (i= 0; i < num_part_fields; i++) + { + if (field->eq(part_field_array[i])) + return TRUE; + } + for (i= 0; i < num_subpart_fields; i++) + { + if (field->eq(subpart_field_array[i])) + return TRUE; + } + return FALSE; +} + #else /* WITH_PARTITION_STORAGE_ENGINE */ /* For builds without partitioning we need to define these functions diff --git a/sql/partition_info.h b/sql/partition_info.h index b271ff08e82..0f38c87dd4e 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -384,6 +384,7 @@ private: bool is_full_part_expr_in_fields(List<Item> &fields); public: bool has_unique_name(partition_element *element); + bool field_in_partition_expr(Field *field) const; }; uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 739930f46fc..7d73a894bdc 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -30,6 +30,7 @@ #include "opt_range.h" #include "my_atomic.h" #include "sql_show.h" +#include "sql_partition.h" /* The system variable 'use_stat_tables' can take one of the @@ -3722,6 +3723,22 @@ void set_statistics_for_table(THD *thd, TABLE *table) (use_stat_table_mode <= COMPLEMENTARY || !table->stats_is_read || read_stats->cardinality_is_null) ? table->file->stats.records : read_stats->cardinality; + + /* + For partitioned table, EITS statistics is based on data from all partitions. + + On the other hand, Partition Pruning figures which partitions will be + accessed and then computes the estimate of rows in used_partitions. + + Use the estimate from Partition Pruning as it is typically more precise. + Ideally, EITS should provide per-partition statistics but this is not + implemented currently. + */ + #ifdef WITH_PARTITION_STORAGE_ENGINE + if (table->part_info) + table->used_stat_records= table->file->stats.records; + #endif + KEY *key_info, *key_info_end; for (key_info= table->key_info, key_info_end= key_info+table->s->keys; key_info < key_info_end; key_info++) @@ -4037,3 +4054,31 @@ bool is_stat_table(const char *db, const char *table) } return false; } + +/* + Check wheter we can use EITS statistics for a field or not + + TRUE : Use EITS for the columns + FALSE: Otherwise +*/ + +bool is_eits_usable(Field *field) +{ + partition_info *part_info= NULL; + #ifdef WITH_PARTITION_STORAGE_ENGINE + part_info= field->table->part_info; + #endif + /* + (1): checks if we have EITS statistics for a particular column + (2): Don't use EITS for GEOMETRY columns + (3): Disabling reading EITS statistics for columns involved in the + partition list of a table. We assume the selecticivity for + such columns would be handled during partition pruning. + */ + Column_statistics* col_stats= field->read_stats; + if (col_stats && !col_stats->no_stat_values_provided() && //(1) + field->type() != MYSQL_TYPE_GEOMETRY && //(2) + (!part_info || !part_info->field_in_partition_expr(field))) //(3) + return TRUE; + return FALSE; +} diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index d30691c32f0..6530c2d6c8f 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -112,6 +112,7 @@ double get_column_range_cardinality(Field *field, key_range *max_endp, uint range_flag); bool is_stat_table(const char *db, const char *table); +bool is_eits_usable(Field* field); class Histogram { |
