@ -948,9 +948,8 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
uint mrr_buf_size , MEM_ROOT * alloc ) ;
uint mrr_buf_size , MEM_ROOT * alloc ) ;
static TRP_RANGE * get_key_scans_params ( PARAM * param , SEL_TREE * tree ,
static TRP_RANGE * get_key_scans_params ( PARAM * param , SEL_TREE * tree ,
bool index_read_must_be_used ,
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
static
TRP_INDEX_INTERSECT * get_best_index_intersect ( PARAM * param , SEL_TREE * tree ,
TRP_INDEX_INTERSECT * get_best_index_intersect ( PARAM * param , SEL_TREE * tree ,
double read_time ) ;
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 */
/* Get best 'range' plan and prepare data for making other plans */
if ( ( range_trp = get_key_scans_params ( & param , tree , FALSE , TRUE ,
if ( ( range_trp = get_key_scans_params ( & param , tree , FALSE , TRUE ,
best_read_time , FALSE ) ) )
best_read_time ) ) )
{
{
best_trp = range_trp ;
best_trp = range_trp ;
best_read_time = best_trp - > read_cost ;
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 ;
double roru_index_costs ;
ha_rows roru_total_records ;
ha_rows roru_total_records ;
double roru_intersect_part = 1.0 ;
double roru_intersect_part = 1.0 ;
bool only_ror_scans_required = FALSE ;
DBUG_ENTER ( " get_best_disjunct_quick " ) ;
DBUG_ENTER ( " get_best_disjunct_quick " ) ;
DBUG_PRINT ( " info " , ( " Full table scan cost: %g " , read_time ) ) ;
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 ) ) )
n_child_scans ) ) )
DBUG_RETURN ( NULL ) ;
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 ,
Collect best ' range ' scan for each of disjuncts , and , while doing so ,
analyze possibility of ROR scans . Also calculate some values needed by
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 ,
DBUG_EXECUTE ( " info " , print_sel_tree ( param , * ptree , & ( * ptree ) - > keys_map ,
" tree in SEL_IMERGE " ) ; ) ;
" tree in SEL_IMERGE " ) ; ) ;
if ( ! ( * cur_child = get_key_scans_params ( param , * ptree , TRUE , FALSE ,
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
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
a random order
2. the functions that estimate the cost of a range scan and an
2. the functions that estimate the cost of a range scan and an
index merge retrievals are not well calibrated
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 ) ;
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
tree make range select for this SEL_TREE
index_read_must_be_used if TRUE , assume ' index only ' option will be set
index_read_must_be_used if TRUE , assume ' index only ' option will be set
( except for clustered PK indexes )
( 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 .
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
RETURN
Best range read plan
Best range read plan
NULL if no plan found or error occurred
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 ,
static TRP_RANGE * get_key_scans_params ( PARAM * param , SEL_TREE * tree ,
bool index_read_must_be_used ,
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 ;
uint idx ;
SEL_ARG * * key , * * end , * * key_to_read = NULL ;
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 ) ;
( bool ) param - > table - > covering_keys . is_set ( keynr ) ;
found_records = check_quick_select ( param , idx , read_index_only , * key ,
found_records = check_quick_select ( param , idx , read_index_only , * key ,
update_tbl_stat s, & mrr_flags ,
for_range_acces s, & mrr_flags ,
& buf_size , & cost ) ;
& 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 */
/* The scan is not a ROR-scan, just skip it */
continue ;
continue ;