mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Implement cost_of_filesort()
The sort length is extracted similarly to how sortlength() function does it. The function makes use of filesort_use_addons function to compute the length of addon fields. Finally, by calling compute_sort_costs we get the fastest_sort possible. Other changes: * Sort_param::using_addon_fields() assumes addon fields are already allocated. This makes the use of Sort_param unusable for compute_sort_costs *if* we don't want to allocate addon fields. As a preliminary fix, pass "with_addon_fields" as bool value to compute_sort_costs() and make the internal functions use that value instead of Sort_param::using_addon_fields() method. The ideal fix would be to define a "leaner" struct with only the necessary members, but this can be done as a separate commit. Reviewer: Monty
This commit is contained in:
parent
b70290869e
commit
59193ef673
3 changed files with 80 additions and 6 deletions
|
@ -221,6 +221,7 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort,
|
|||
bool allow_packing_for_sortkeys;
|
||||
Bounded_queue<uchar, uchar> 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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,8 @@
|
|||
#include "my_global.h"
|
||||
#include "my_base.h"
|
||||
#include "sql_array.h"
|
||||
#include "handler.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue