diff --git a/sql/filesort.cc b/sql/filesort.cc index 193b52c9bba..071108f7e91 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -221,6 +221,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, bool allow_packing_for_sortkeys; Bounded_queue pq; SQL_SELECT *const select= filesort->select; + Sort_costs costs; ha_rows limit_rows= filesort->limit; uint s_length= 0, sort_len; Sort_keys *sort_keys; @@ -266,7 +267,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, param.sort_keys= sort_keys; sort_len= sortlength(thd, sort_keys, &allow_packing_for_sortkeys); - param.init_for_filesort(sort_len, table, limit_rows, filesort); + param.init_for_filesort(table, filesort, sort_len, limit_rows); if (!param.accepted_rows) param.accepted_rows= ¬_used; @@ -286,7 +287,6 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, // If number of rows is not known, use as much of sort buffer as possible. num_rows= table->file->estimate_rows_upper_bound(); - Sort_costs costs; costs.compute_sort_costs(¶m, num_rows, memory_available, param.using_addon_fields()); diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc index 1989f9ce2bd..4a75817add4 100644 --- a/sql/filesort_utils.cc +++ b/sql/filesort_utils.cc @@ -23,6 +23,13 @@ PSI_memory_key key_memory_Filesort_buffer_sort_keys; +const LEX_CSTRING filesort_names[]= +{ + { STRING_WITH_LEN("priority_queue with addon fields")}, + { STRING_WITH_LEN("priority_queue with row lookup")}, + { STRING_WITH_LEN("merge_sort with addon fields")}, + { STRING_WITH_LEN("merge_sort with row lookup)")} +}; /* Different ways to do sorting: @@ -51,7 +58,7 @@ PSI_memory_key key_memory_Filesort_buffer_sort_keys; */ static -double get_qsort_sort_cost(size_t num_rows, bool with_addon_fields) +double get_qsort_sort_cost(ha_rows num_rows, bool with_addon_fields) { const double row_copy_cost= with_addon_fields ? DEFAULT_ROW_COPY_COST : DEFAULT_KEY_COPY_COST; @@ -397,3 +404,66 @@ void Filesort_buffer::sort_buffer(const Sort_param *param, uint count) param->get_compare_function(), param->get_compare_argument(&size)); } + + +static +size_t get_sort_length(THD *thd, Item_field *item) +{ + SORT_FIELD_ATTR sort_attr; + sort_attr.type= ((item->field)->is_packable() ? + SORT_FIELD_ATTR::VARIABLE_SIZE : + SORT_FIELD_ATTR::FIXED_SIZE); + item->type_handler()->sort_length(thd, item, &sort_attr); + + return sort_attr.length + (item->maybe_null() ? 1 : 0); +} + + +/** + Calculate the cost of doing a filesort + + @param table Table to sort + @param Order_by Fields to sort + @param rows_to_read Number of rows to be sorted + @param limit_rows Number of rows in result (when using limit) + @param used_sort_type Set to the sort algorithm used + + @result cost of sorting +*/ + + +double cost_of_filesort(TABLE *table, ORDER *order_by, ha_rows rows_to_read, + ha_rows limit_rows, enum sort_type *used_sort_type) +{ + THD *thd= table->in_use; + Sort_costs costs; + Sort_param param; + size_t memory_available= (size_t) thd->variables.sortbuff_size; + uint sort_len= 0; + uint addon_field_length, num_addon_fields, num_nullable_fields; + uint packable_length; + bool with_addon_fields; + + for (ORDER *ptr= order_by; ptr ; ptr= ptr->next) + { + Item_field *field= (Item_field*) (*ptr->item)->real_item(); + size_t length= get_sort_length(table->in_use, field); + set_if_smaller(length, thd->variables.max_sort_length); + sort_len+= (uint) length; + } + + with_addon_fields= + filesort_use_addons(table, sort_len, &addon_field_length, + &num_addon_fields, &num_nullable_fields, + &packable_length); + + /* Fill in the Sort_param structure so we can compute the sort costs */ + param.setup_lengths_and_limit(table, sort_len, addon_field_length, + limit_rows); + + costs.compute_sort_costs(¶m, rows_to_read, memory_available, + with_addon_fields); + + *used_sort_type= costs.fastest_sort; + return costs.lowest_cost; +} diff --git a/sql/filesort_utils.h b/sql/filesort_utils.h index d3684bab770..1e1ddee06c0 100644 --- a/sql/filesort_utils.h +++ b/sql/filesort_utils.h @@ -19,10 +19,8 @@ #include "my_global.h" #include "my_base.h" #include "sql_array.h" +#include "handler.h" -#include - -class TABLE; class Sort_param; /** @@ -349,6 +347,12 @@ private: longlong m_idx; }; +/* Names for sort_type */ +extern const LEX_CSTRING filesort_names[]; + +double cost_of_filesort(TABLE *table, ORDER *order_by, ha_rows rows_to_read, + ha_rows limit_rows, enum sort_type *used_sort_type); + int compare_packed_sort_keys(void *sort_keys, unsigned char **a, unsigned char **b); qsort2_cmp get_packed_keys_compare_ptr();