Skip to content

Commit 922fcc6

Browse files
committed
Use range instead of ref when we know that range is equal or better.
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.
1 parent ae05097 commit 922fcc6

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

sql/sql_select.cc

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8567,7 +8567,8 @@ best_access_path(JOIN *join,
85678567
*/
85688568
if (table->opt_range_keys.is_set(key) && !found_ref && //(C1)
85698569
table->opt_range[key].key_parts == max_key_part && //(C2)
8570-
table->opt_range[key].ranges == 1 + MY_TEST(ref_or_null_part)) //(C3)
8570+
(table->opt_range[key].ranges ==
8571+
1 + MY_TEST(ref_or_null_part))) //(C3)
85718572
{
85728573
records= (double) table->opt_range[key].rows;
85738574
table->opt_range[key].get_costs(&tmp);
@@ -8601,17 +8602,34 @@ best_access_path(JOIN *join,
86018602
*/
86028603
if (table->opt_range_keys.is_set(key))
86038604
{
8605+
double rows;
86048606
if (table->opt_range[key].key_parts >= max_key_part) // (2)
86058607
{
8606-
double rows= (double) table->opt_range[key].rows;
8607-
if (!found_ref && // (1)
8608-
records < rows) // (3)
8608+
/*
8609+
Choose range over REF in the case range will always be
8610+
as good or better than REF.
8611+
This is the case when we have only one const range
8612+
and it consist of more parts than what we used for REF.
8613+
*/
8614+
if (!found_ref &&
8615+
table->opt_range[key].key_parts > max_key_part &&
8616+
table->opt_range[key].ranges <=
8617+
(uint) (1 + MY_TEST(ref_or_null_part)))
86098618
{
8610-
trace_access_idx.add("used_range_estimates",
8611-
"clipped up");
8612-
records= rows;
8619+
trace_access_idx.
8620+
add("chosen", false).
8621+
add("cause", "range is simple and more selective");
8622+
continue; // continue with next key
86138623
}
86148624
}
8625+
rows= (double) table->opt_range[key].rows;
8626+
if (!found_ref && // (1)
8627+
records < rows) // (3)
8628+
{
8629+
trace_access_idx.add("used_range_estimates",
8630+
"clipped up");
8631+
records= rows;
8632+
}
86158633
}
86168634
}
86178635
else

0 commit comments

Comments
 (0)