summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2020-04-17 20:58:55 -0700
committerIgor Babaev <igor@askmonty.org>2020-04-17 20:58:55 -0700
commit29cdd5082279ab5bcae04464a08b2499444c86f5 (patch)
treea695d61194aa9685a13530408c79fdc55eabce8f /sql/opt_range.cc
parent280b158501fdb889beee3a0ea0b9acbf723acf66 (diff)
downloadmariadb-git-29cdd5082279ab5bcae04464a08b2499444c86f5.tar.gz
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.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc34
1 files changed, 16 insertions, 18 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 9e96e94ac91..5658bb065b7 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -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;