diff options
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d3104019edb..7599401dcb4 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3250,6 +3250,25 @@ double records_in_column_ranges(PARAM *param, uint idx, /* + Compare quick select ranges according to number of found rows + If there is equal amounts of rows, use the long key part. + The idea is that if we have keys (a),(a,b) and (a,b,c) and we have + a query like WHERE a=1 and b=1 and c=1, + it is better to use key (a,b,c) than (a) as it will ensure we don't also + use histograms for columns b and c +*/ + +static +int cmp_quick_ranges(TABLE *table, uint *a, uint *b) +{ + int tmp= CMP_NUM(table->quick_rows[*a], table->quick_rows[*b]); + if (tmp) + return tmp; + return -CMP_NUM(table->quick_key_parts[*a], table->quick_key_parts[*b]); +} + + +/* Calculate the selectivity of the condition imposed on the rows of a table SYNOPSIS @@ -3285,10 +3304,10 @@ double records_in_column_ranges(PARAM *param, uint idx, bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) { - uint keynr; - uint max_quick_key_parts= 0; + uint keynr, range_index, ranges; MY_BITMAP *used_fields= &table->cond_set; - double table_records= (double)table->stat_records(); + double table_records= (double)table->stat_records(); + uint optimal_key_order[MAX_KEY]; DBUG_ENTER("calculate_cond_selectivity_for_table"); table->cond_selectivity= 1.0; @@ -3327,23 +3346,21 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) Json_writer_object trace_wrapper(thd); Json_writer_array selectivity_for_indexes(thd, "selectivity_for_indexes"); - for (keynr= 0; keynr < table->s->keys; keynr++) - { + /* + Walk through all quick ranges in the order of least found rows. + */ + for (ranges= keynr= 0 ; keynr < table->s->keys; keynr++) if (table->quick_keys.is_set(keynr)) - set_if_bigger(max_quick_key_parts, table->quick_key_parts[keynr]); - } + optimal_key_order[ranges++]= keynr; - /* - Walk through all indexes, indexes where range access uses more keyparts - go first. - */ - for (uint quick_key_parts= max_quick_key_parts; - quick_key_parts; quick_key_parts--) + my_qsort2(optimal_key_order, ranges, + sizeof(optimal_key_order[0]), + (qsort2_cmp) cmp_quick_ranges, table); + + for (range_index= 0 ; range_index < ranges ; range_index++) { - for (keynr= 0; keynr < table->s->keys; keynr++) + uint keynr= optimal_key_order[range_index]; { - if (table->quick_keys.is_set(keynr) && - table->quick_key_parts[keynr] == quick_key_parts) { uint i; uint used_key_parts= table->quick_key_parts[keynr]; |