mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-17155: Incorrect ORDER BY optimization: full index scan is used instead of range
The bug was this scenario: 1. Join optimizer picks a range plan on index IDX1 (This index doesn't match the ORDER BY clause, so sorting will be needed) 2. Index Condition Pushdown pushes a part of WHERE down. The pushed condition is removed from SQL_SELECT::cond 3. test_if_skip_sort_order() figures that it's better to use IDX2 (as it will match ORDER BY ... LIMIT and so will execute faster) 3.1 It sees that there was a possible range access on IDX2. It tries to construct it by calling SQL_SELECT::test_quick_select(), but alas, SQL_SELECT::cond doesn't have all parts of WHERE anymore. So it uses full index scan which is slow. (The execution works fine because there's code further in test_if_skip_sort_order() which "Unpushes" the index condition and restores the original WHERE clause. It was just the test_quick_select call that suffered).
This commit is contained in:
@ -21244,11 +21244,30 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
tmp_map.clear_all(); // Force the creation of quick select
|
||||
tmp_map.set_bit(best_key); // only best_key.
|
||||
select->quick= 0;
|
||||
|
||||
bool cond_saved= false;
|
||||
Item *saved_cond;
|
||||
|
||||
/*
|
||||
Index Condition Pushdown may have removed parts of the condition for
|
||||
this table. Temporarily put them back because we want the whole
|
||||
condition for the range analysis.
|
||||
*/
|
||||
if (select->pre_idx_push_select_cond)
|
||||
{
|
||||
saved_cond= select->cond;
|
||||
select->cond= select->pre_idx_push_select_cond;
|
||||
cond_saved= true;
|
||||
}
|
||||
|
||||
select->test_quick_select(join->thd, tmp_map, 0,
|
||||
join->select_options & OPTION_FOUND_ROWS ?
|
||||
HA_POS_ERROR :
|
||||
join->unit->select_limit_cnt,
|
||||
TRUE, FALSE, FALSE);
|
||||
|
||||
if (cond_saved)
|
||||
select->cond= saved_cond;
|
||||
}
|
||||
order_direction= best_key_direction;
|
||||
/*
|
||||
|
Reference in New Issue
Block a user