diff options
author | Igor Babaev <igor@askmonty.org> | 2013-03-31 23:41:47 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-03-31 23:41:47 -0700 |
commit | e37053049341e425e139dd5bb723f1d99f56a2ad (patch) | |
tree | 4b08c86257b2445cd2718a8054fbb15f4a4ae0b5 /sql/sql_statistics.cc | |
parent | cb47f0a79fa527bdb2fd5a0f05a9238bb2e92fe5 (diff) | |
download | mariadb-git-e37053049341e425e139dd5bb723f1d99f56a2ad.tar.gz |
Take into account the number of null values in any used column when
calculating selectivity of conditions.
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r-- | sql/sql_statistics.cc | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 74ed90cf7a1..736fb3e1f91 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3342,25 +3342,41 @@ double get_column_range_cardinality(Field *field, double res; TABLE *table= field->table; Column_statistics *col_stats= table->field[field->field_index]->read_stats; + double tab_records= table->stat_records(); if (!col_stats) - res= table->stat_records(); + return tab_records; + + double col_nulls= tab_records * col_stats->get_nulls_ratio(); + + double col_non_nulls= tab_records - col_nulls; + + if (col_non_nulls < 1) + res= 0; else if (min_endp && max_endp && min_endp->length == max_endp->length && !memcmp(min_endp->key, max_endp->key, min_endp->length)) { - double avg_frequency= col_stats->get_avg_frequency(); - res= avg_frequency; - if (avg_frequency > 1.0 + 0.000001 && - col_stats->min_value && col_stats->max_value) + if (field->null_ptr && min_endp->key[0]) { - Histogram *hist= &col_stats->histogram; - if (hist->get_size() > 0) + /* This is null single point range */ + res= col_nulls; + } + else + { + double avg_frequency= col_stats->get_avg_frequency(); + res= avg_frequency; + if (avg_frequency > 1.0 + 0.000001 && + col_stats->min_value && col_stats->max_value) { - double pos= field->middle_point_pos(col_stats->min_value, - col_stats->max_value); - res= table->stat_records() * - hist->point_selectivity(pos, - avg_frequency / table->stat_records()); + Histogram *hist= &col_stats->histogram; + if (hist->get_size() > 0) + { + double pos= field->middle_point_pos(col_stats->min_value, + col_stats->max_value); + res= col_non_nulls * + hist->point_selectivity(pos, + avg_frequency / col_non_nulls); + } } } } @@ -3394,10 +3410,10 @@ double get_column_range_cardinality(Field *field, sel= (max_mp_pos - min_mp_pos); else sel= hist->range_selectivity(min_mp_pos, max_mp_pos); - res= table->stat_records() * sel; + res= col_non_nulls * sel; } else - res= table->stat_records(); + res= col_non_nulls; } return res; } |