1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

MDEV-6735: Range checked for each record used with key (also MDEV-7786, MDEV-7923)

"Range Checked for Each Record" should be only employed when the other
option would be cross-product join (i.e. the other option is so bad that
we hardly risk anything).

Previous logic was: use RCfER if there are no possible quick selects, or
quick select would read > 100 rows. Also, it didn't always work as
expected due to range optimizer changing table->quick_keys and us
looking at sel->quick_keys.

Another angle is that recent versions have enabled use of Join Buffering
in e.g. outer joins. This further reduces the range of cases where RCfER
should be used.

We are still unable to estimate the cost of RCfER with any precision, so
now changing the condition of "no quick select or quick->records> 100"
to a hopefully better condition "no quick select or quick would cost more
than full table scan".
This commit is contained in:
Sergei Petrunia
2015-06-09 18:56:09 +03:00
parent 5d57e2d8cd
commit 992d782d78
3 changed files with 102 additions and 2 deletions

View File

@@ -9013,10 +9013,24 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (!sel->quick_keys.is_subset(tab->checked_keys) ||
!sel->needed_reg.is_subset(tab->checked_keys))
{
/*
"Range checked for each record" is a "last resort" access method
that should only be used when the other option is a cross-product
join.
We use the following condition (it's approximate):
1. There are potential keys for (sel->needed_reg)
2. There were no possible ways to construct a quick select, or
the quick select would be more expensive than the full table
scan.
*/
tab->use_quick= (!sel->needed_reg.is_clear_all() &&
(sel->quick_keys.is_clear_all() ||
(sel->quick &&
(sel->quick->records >= 100L)))) ?
(sel->quick &&
sel->quick->read_time >
tab->table->file->scan_time() +
tab->table->file->stats.records/TIME_FOR_COMPARE
))) ?
2 : 1;
sel->read_tables= used_tables & ~current_map;
sel->quick_keys.clear_all();