Commit 29cdd508 authored by Igor Babaev's avatar Igor Babaev

MDEV-21932 Another attempt to fix the bug .

The first patch for the bug was erroneous: it did not take into account
the fact that the modified function get_key_scans_params() was called in
different contexts. As a result the patch caused a regression bug MDEV-22191.
The patch for this bug introduced an extra parameter. Actually we can
do without this parameter and use the fourth parameter for the same
puropose - to differentiate between the calls of the function for range
access and for index merge access.

Also removed the call of get_key_scans_params() in the code of the function
merge_same_index_scans() as not needed.
parent 280b1585
......@@ -948,9 +948,8 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
uint mrr_buf_size, MEM_ROOT *alloc);
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
double read_time,
bool ror_scans_required);
bool for_range_access,
double read_time);
static
TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
double read_time);
......@@ -3147,7 +3146,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
/* Get best 'range' plan and prepare data for making other plans */
if ((range_trp= get_key_scans_params(&param, tree, FALSE, TRUE,
best_read_time, FALSE)))
best_read_time)))
{
best_trp= range_trp;
best_read_time= best_trp->read_cost;
......@@ -4673,7 +4672,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
double roru_index_costs;
ha_rows roru_total_records;
double roru_intersect_part= 1.0;
bool only_ror_scans_required= FALSE;
DBUG_ENTER("get_best_disjunct_quick");
DBUG_PRINT("info", ("Full table scan cost: %g", read_time));
......@@ -4700,8 +4698,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
n_child_scans)))
DBUG_RETURN(NULL);
only_ror_scans_required= !optimizer_flag(param->thd,
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION);
/*
Collect best 'range' scan for each of disjuncts, and, while doing so,
analyze possibility of ROR scans. Also calculate some values needed by
......@@ -4714,8 +4710,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
"tree in SEL_IMERGE"););
if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE,
read_time,
only_ror_scans_required)))
read_time)))
{
/*
One of index scans in this index_merge is more expensive than entire
......@@ -5035,9 +5030,12 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
a random order
2. the functions that estimate the cost of a range scan and an
index merge retrievals are not well calibrated
As the best range access has been already chosen it does not
make sense to evaluate the one obtained from a degenerated
index merge.
*/
trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE,
read_time, FALSE);
trp= 0;
}
DBUG_RETURN(trp);
......@@ -6753,9 +6751,9 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
tree make range select for this SEL_TREE
index_read_must_be_used if TRUE, assume 'index only' option will be set
(except for clustered PK indexes)
for_range_access if TRUE the function is called to get the best range
plan for range access, not for index merge access
read_time don't create read plans with cost > read_time.
only_ror_scans_required set to TRUE when we are only interested
in ROR scan
RETURN
Best range read plan
NULL if no plan found or error occurred
......@@ -6763,9 +6761,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
double read_time,
bool only_ror_scans_required)
bool for_range_access,
double read_time)
{
uint idx;
SEL_ARG **key,**end, **key_to_read= NULL;
......@@ -6809,10 +6806,11 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
(bool) param->table->covering_keys.is_set(keynr);
found_records= check_quick_select(param, idx, read_index_only, *key,
update_tbl_stats, &mrr_flags,
for_range_access, &mrr_flags,
&buf_size, &cost);
if (only_ror_scans_required && !param->is_ror_scan)
if (!for_range_access && !param->is_ror_scan &&
!optimizer_flag(param->thd,OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
{
/* The scan is not a ROR-scan, just skip it */
continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment