diff options
author | Igor Babaev <igor@askmonty.org> | 2019-09-12 23:00:49 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2019-09-12 23:01:11 -0700 |
commit | deb9121fdf2152752346c767321e6e01aa5d6c69 (patch) | |
tree | 403ebd9fd662ed8407dceba77fed6738f32d8a3a /sql/opt_range.cc | |
parent | d6f0e60a67a5e81dc6fd90a117db2aa5fb658664 (diff) | |
download | mariadb-git-deb9121fdf2152752346c767321e6e01aa5d6c69.tar.gz |
MDEV-20576 A new assertion added to check validity of calculated
selectivity values fails
After having set the assertion that checks validity of selectivity values
returned by the function table_cond_selectivity() a test case from
order_by.tesst failed. The failure occurred because range optimizer could
return as an estimate of the cardinality of the ranges built for an index
a number exceeding the total number of records in the table.
The second bug is more subtle. It may happen when there are several
indexes with same prefix defined on the first joined table t accessed by
a constant ref access. In this case the range optimizer estimates the
number of accessed records of t for each usable index and these
estimates can be different. Only the first of these estimates is taken
into account when the selectivity of the ref access is calculated.
However the optimizer later can choose a different index that provides
a different estimate. The function table_condition_selectivity() could use
this estimate to discount the selectivity of the ref access. This could
lead to an selectivity value returned by this function that was greater
that 1.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e8421ad052a..45dad8882a1 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -10179,6 +10179,16 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, bufsize, mrr_flags, cost); if (rows != HA_POS_ERROR) { + ha_rows table_records= param->table->stat_records(); + if (rows > table_records) + { + /* + For any index the total number of records within all ranges + cannot be be bigger than the number of records in the table + */ + rows= table_records; + set_if_bigger(rows, 1); + } param->quick_rows[keynr]= rows; param->possible_keys.set_bit(keynr); if (update_tbl_stats) |