1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MDEV-17761: Odd optimizer choice with ORDER BY LIMIT and condition selectivity

Make the "ORDER BY ... LIMIT n" optimizer take into account condition
selectivity data from EITS (not just from potential range accesses).
This commit is contained in:
Sergei Petrunia
2019-01-23 15:49:49 +03:00
parent 36a2a185fe
commit b7a784ae25
5 changed files with 145 additions and 0 deletions

View File

@ -26884,7 +26884,11 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
uint tablenr= (uint)(tab - join->join_tab);
read_time= join->best_positions[tablenr].read_time;
for (uint i= tablenr+1; i < join->table_count; i++)
{
fanout*= join->best_positions[i].records_read; // fanout is always >= 1
// But selectivity is =< 1 :
fanout*= join->best_positions[i].cond_selectivity;
}
}
else
read_time= table->file->scan_time();
@ -27022,6 +27026,23 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
*/
select_limit= (ha_rows) (select_limit < fanout ?
1 : select_limit/fanout);
/*
refkey_rows_estimate is E(#rows) produced by the table access
strategy that was picked without regard to ORDER BY ... LIMIT.
It will be used as the source of selectivity data.
Use table->cond_selectivity as a better estimate which includes
condition selectivity too.
*/
{
// we use MIN(...), because "Using LooseScan" queries have
// cond_selectivity=1 while refkey_rows_estimate has a better
// estimate.
refkey_rows_estimate= MY_MIN(refkey_rows_estimate,
table_records * table->cond_selectivity);
}
/*
We assume that each of the tested indexes is not correlated
with ref_key. Thus, to select first N records we have to scan
@ -27032,6 +27053,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
N/(refkey_rows_estimate/table_records) > table_records
<=> N > refkey_rows_estimate.
*/
if (select_limit > refkey_rows_estimate)
select_limit= table_records;
else