diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7a47dd309c1..235de14c466 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -24527,7 +24527,7 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, double fanout= 1; ha_rows table_records= table->stat_records(); bool group= join && join->group && order == join->group_list; - ha_rows ref_key_quick_rows= HA_POS_ERROR; + ha_rows refkey_rows_estimate= table->quick_condition_rows; const bool has_limit= (select_limit_arg != HA_POS_ERROR); /* @@ -24553,10 +24553,6 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, else keys= usable_keys; - if (ref_key >= 0 && ref_key != MAX_KEY && - table->covering_keys.is_set(ref_key)) - ref_key_quick_rows= table->quick_rows[ref_key]; - if (join) { uint tablenr= tab - join->join_tab; @@ -24567,6 +24563,22 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, else read_time= table->file->scan_time(); + /* + Calculate the selectivity of the ref_key for REF_ACCESS. For + RANGE_ACCESS we use table->quick_condition_rows. + */ + if (ref_key >= 0 && tab->type == JT_REF) + { + if (table->quick_keys.is_set(ref_key)) + refkey_rows_estimate= table->quick_rows[ref_key]; + else + { + const KEY *ref_keyinfo= table->key_info + ref_key; + refkey_rows_estimate= ref_keyinfo->rec_per_key[tab->ref.key_parts - 1]; + } + set_if_bigger(refkey_rows_estimate, 1); + } + for (nr=0; nr < table->s->keys ; nr++) { int direction; @@ -24683,17 +24695,17 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, with ref_key. Thus, to select first N records we have to scan N/selectivity(ref_key) index entries. selectivity(ref_key) = #scanned_records/#table_records = - table->quick_condition_rows/table_records. + refkey_rows_estimate/table_records. In any case we can't select more than #table_records. - N/(table->quick_condition_rows/table_records) > table_records - <=> N > table->quick_condition_rows. - */ - if (select_limit > table->quick_condition_rows) + N/(refkey_rows_estimate/table_records) > table_records + <=> N > refkey_rows_estimate. + */ + if (select_limit > refkey_rows_estimate) select_limit= table_records; else select_limit= (ha_rows) (select_limit * (double) table_records / - table->quick_condition_rows); + refkey_rows_estimate); rec_per_key= keyinfo->actual_rec_per_key(keyinfo->user_defined_key_parts-1); set_if_bigger(rec_per_key, 1); /* @@ -24713,8 +24725,12 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table, index_scan_time < read_time) { ha_rows quick_records= table_records; + ha_rows refkey_select_limit= (ref_key >= 0 && + table->covering_keys.is_set(ref_key)) ? + refkey_rows_estimate : + HA_POS_ERROR; if ((is_best_covering && !is_covering) || - (is_covering && ref_key_quick_rows < select_limit)) + (is_covering && refkey_select_limit < select_limit)) continue; if (table->quick_keys.is_set(nr)) quick_records= table->quick_rows[nr]; |