Skip to content

Commit

Permalink
Fixed wrong selectivity calculation in table_after_join_selectivity()
Browse files Browse the repository at this point in the history
The old code counted selectivity double in case of queries like:
WHERE key_part1=1 and key_part2 < 100
if the optimizer would decide to use a REF access on key_part1.

The new code in best_access_path() that changes REF access to RANGE
if the RANGE key is longer makes this issue less likely to happen.

I was not able to create a test case for 11.0, however if one ports this
patch to a MariaDB version without the change of REF to RANGE, the
selectivity will be counted double.
  • Loading branch information
montywi authored and spetrunia committed Feb 3, 2023
1 parent ed0a723 commit b5df077
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10440,14 +10440,15 @@ double table_after_join_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
{
key_part_map quick_key_map= (key_part_map(1) <<
table->opt_range[key].key_parts) - 1;
if ((table->opt_range[key].rows &&
!(quick_key_map & ~table->const_key_parts[key])) ||
s->type == JT_RANGE)
if (s->type == JT_RANGE ||
(table->opt_range[key].rows && (table->const_key_parts[key] & 1)))
{
/*
Ok, there is an equality for each of the key parts used by the
quick select. This means, quick select's estimate can be reused to
discount the selectivity of a prefix of a ref access.
/*
We are either using a range or we are using a REF which the
same key as an active range and the first key part is a constant.

In both cases we have to discount the selectivity for the range
as otherwise we are using the selectivity twice.
*/
for (; quick_key_map & 1 ; quick_key_map>>= 1)
{
Expand Down

0 comments on commit b5df077

Please sign in to comment.