Skip to content

Commit

Permalink
Use range instead of ref when we know that range is equal or better.
Browse files Browse the repository at this point in the history
This stabilizes main.order_by_optimizer_innodb, where the result varies
depending on the rec_per_key status from the engine.

The logic to prefer range over a const ref:
- If range of has only one part and it uses more key parts than ref, then
  use the range.

Example:
WHERE key_part1=1 and key_part2 > #
Here we will prefer a range over (key_part1,key_part2) instead a ref
over key_part1.
  • Loading branch information
montywi committed Mar 3, 2023
1 parent ae05097 commit 922fcc6
Showing 1 changed file with 25 additions and 7 deletions.
32 changes: 25 additions & 7 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8567,7 +8567,8 @@ best_access_path(JOIN *join,
*/
if (table->opt_range_keys.is_set(key) && !found_ref && //(C1)
table->opt_range[key].key_parts == max_key_part && //(C2)
table->opt_range[key].ranges == 1 + MY_TEST(ref_or_null_part)) //(C3)
(table->opt_range[key].ranges ==
1 + MY_TEST(ref_or_null_part))) //(C3)
{
records= (double) table->opt_range[key].rows;
table->opt_range[key].get_costs(&tmp);
Expand Down Expand Up @@ -8601,17 +8602,34 @@ best_access_path(JOIN *join,
*/
if (table->opt_range_keys.is_set(key))
{
double rows;
if (table->opt_range[key].key_parts >= max_key_part) // (2)
{
double rows= (double) table->opt_range[key].rows;
if (!found_ref && // (1)
records < rows) // (3)
/*
Choose range over REF in the case range will always be
as good or better than REF.
This is the case when we have only one const range
and it consist of more parts than what we used for REF.
*/
if (!found_ref &&
table->opt_range[key].key_parts > max_key_part &&
table->opt_range[key].ranges <=
(uint) (1 + MY_TEST(ref_or_null_part)))
{
trace_access_idx.add("used_range_estimates",
"clipped up");
records= rows;
trace_access_idx.
add("chosen", false).
add("cause", "range is simple and more selective");
continue; // continue with next key
}
}
rows= (double) table->opt_range[key].rows;
if (!found_ref && // (1)
records < rows) // (3)
{
trace_access_idx.add("used_range_estimates",
"clipped up");
records= rows;
}
}
}
else
Expand Down

0 comments on commit 922fcc6

Please sign in to comment.