You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug #23259872: OPTIMIZER CHOOSES TO USE NON PRIMARY INDEX,
EVEN THOUGH COST IS HIGHER
Issue:
------
Optimizer tries to choose between a range-access and
ref-access, based on various parameters like
records_per_key, CPU cost and I/O cost. When the
row-estimate for ref access is inaccurate, optimizer
uses the estimate from range access on the same index.
In the current issue the ref access's row-estimate comes
from range-access's estimate. The ref-access on a secondary
index is calculated to be cheaper than the best
range-access on the primary key. This will result in a bad
performance.
Solution (mysql-trunk):
---------
Ignore the index for ref access when we have the above mentioned
problem.
Solution (mysql-5.7):
---------
Shift from ref-access to range-access when:
1) Ref-access row estimate is overly-optimistic and it has
borrowed range-access's estimate on the same index.
2) Range-access uses more index key parts than ref access.
We already do this in cases where the above conditions are
met and range access on the same index is the cheapest.
With this fix, we shift to range-access on that index, even
if it is not considered the cheapest. To do this, we run
the range optimizer on that index alone.
sql/sql_select.h:
A new boolean 'dodgy_ref_cost' has been added to JOIN_TAB.
Setting this flag means ref is using lesser number of
key-parts than range and it borrows range's row estimate.
sql/sql_planner.h:
find_best_ref should be able to modify the flag
'dodgy_ref_cost', so removing the const.
sql/sql_planner.cc:
In find_best_ref, keep track of whether ref access's
row-estimate is problematic and set the 'dodgy_ref_cost'
flag.
sql/sql_optimizer.cc:
Conditions 3, 4 were earlier tested for negation. Now
they are tested before 2 and false is returned. Check if
the 'dodgy_ref_cost' flag is set. Then it is better we
shift to range on the same index since it uses more
keyparts and its row-estimate is more reliable. We do
this by calling the range optimizer again on that index
alone.
Solution (mysql-5.6):
---------
Same approach as 5.7. With the following changes:
sql/sql_optimizer.cc:
A new function can_switch_from_ref_to_range, similar to the
one in 5.7+ has been created.
0 commit comments