diff options
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d1ebb910448..078b0995d6a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -958,7 +958,7 @@ 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, + bool for_range_access, double read_time); static TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, @@ -5291,6 +5291,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, sizeof(TRP_RANGE*)* n_child_scans))) DBUG_RETURN(NULL); + /* Collect best 'range' scan for each of disjuncts, and, while doing so, analyze possibility of ROR scans. Also calculate some values needed by @@ -5302,7 +5303,8 @@ 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))) + if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, + read_time))) { /* One of index scans in this index_merge is more expensive than entire @@ -5622,9 +5624,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); + trp= 0; } DBUG_RETURN(trp); @@ -7341,6 +7346,8 @@ 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. RETURN Best range read plan @@ -7349,7 +7356,7 @@ 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, + bool for_range_access, double read_time) { uint idx; @@ -7394,9 +7401,16 @@ 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 (!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; + } + if (found_records != HA_POS_ERROR && tree->index_scans && (index_scan= (INDEX_SCAN_INFO *)alloc_root(param->mem_root, sizeof(INDEX_SCAN_INFO)))) @@ -9482,7 +9496,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag) if (key2->next_key_part) { key1->use_count--; // Incremented in and_all_keys - return and_all_keys(param, key1, key2, clone_flag); + return and_all_keys(param, key1, key2->next_key_part, clone_flag); } key2->use_count--; // Key2 doesn't have a tree } |