summaryrefslogtreecommitdiff
path: root/sql/sql_statistics.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-03-31 23:41:47 -0700
committerIgor Babaev <igor@askmonty.org>2013-03-31 23:41:47 -0700
commite37053049341e425e139dd5bb723f1d99f56a2ad (patch)
tree4b08c86257b2445cd2718a8054fbb15f4a4ae0b5 /sql/sql_statistics.cc
parentcb47f0a79fa527bdb2fd5a0f05a9238bb2e92fe5 (diff)
downloadmariadb-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.cc44
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;
}