mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Cleanup of sql_join_cache code (no logic changes)
- Remove virtual from get_min_join_buffer_size() and get_max_join_buffer_size(). - Avoid some calls to get_min_buffer_size() - Simply cache usage in get_..._join_buffer_size() - Simplify get_max_join_buffer_size() when using optimize_buff_size - Reindented some long comments Reviewer: Sergei Petrunia <sergey@mariadb.com>
This commit is contained in:
@ -694,16 +694,22 @@ void JOIN_CACHE::set_constants()
|
|||||||
(prev_cache ? prev_cache->get_size_of_rec_offset() : 0) +
|
(prev_cache ? prev_cache->get_size_of_rec_offset() : 0) +
|
||||||
length + fields*sizeof(uint);
|
length + fields*sizeof(uint);
|
||||||
pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *);
|
pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *);
|
||||||
min_buff_size= 0;
|
|
||||||
min_records= 1;
|
min_records= 1;
|
||||||
|
min_buff_size= get_min_join_buffer_size();
|
||||||
buff_size= (size_t)MY_MAX(join->thd->variables.join_buff_size,
|
buff_size= (size_t)MY_MAX(join->thd->variables.join_buff_size,
|
||||||
get_min_join_buffer_size());
|
min_buff_size);
|
||||||
size_of_rec_ofs= offset_size(buff_size);
|
size_of_rec_ofs= offset_size(buff_size);
|
||||||
size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len);
|
size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len);
|
||||||
size_of_fld_ofs= size_of_rec_len;
|
size_of_fld_ofs= size_of_rec_len;
|
||||||
base_prefix_length= (with_length ? size_of_rec_len : 0) +
|
base_prefix_length= (with_length ? size_of_rec_len : 0) +
|
||||||
(prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
|
(prev_cache ? prev_cache->get_size_of_rec_offset() : 0);
|
||||||
/*
|
/*
|
||||||
|
Call ge_min_join_buffer_size() again as the size may have got smaller
|
||||||
|
if size_of_rec_ofs or some other variable changed since last call.
|
||||||
|
*/
|
||||||
|
min_buff_size= 0;
|
||||||
|
min_buff_size= get_min_join_buffer_size();
|
||||||
|
/*
|
||||||
The size of the offsets for referenced fields will be added later.
|
The size of the offsets for referenced fields will be added later.
|
||||||
The values of 'pack_length' and 'pack_length_with_blob_ptrs' are adjusted
|
The values of 'pack_length' and 'pack_length_with_blob_ptrs' are adjusted
|
||||||
every time when the first reference to the referenced field is registered.
|
every time when the first reference to the referenced field is registered.
|
||||||
@ -767,30 +773,29 @@ uint JOIN_CACHE::get_record_max_affix_length()
|
|||||||
|
|
||||||
size_t JOIN_CACHE::get_min_join_buffer_size()
|
size_t JOIN_CACHE::get_min_join_buffer_size()
|
||||||
{
|
{
|
||||||
if (!min_buff_size)
|
if (min_buff_size)
|
||||||
|
return min_buff_size; // use cached value
|
||||||
|
|
||||||
|
size_t len= 0, len_last= 0, len_addon, min_sz, add_sz= 0;
|
||||||
|
|
||||||
|
for (JOIN_TAB *tab= start_tab; tab != join_tab;
|
||||||
|
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||||
{
|
{
|
||||||
size_t len= 0;
|
len+= tab->get_max_used_fieldlength();
|
||||||
size_t len_last= 0;
|
len_last+= tab->get_used_fieldlength();
|
||||||
for (JOIN_TAB *tab= start_tab; tab != join_tab;
|
|
||||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
|
||||||
{
|
|
||||||
len+= tab->get_max_used_fieldlength();
|
|
||||||
len_last+= tab->get_used_fieldlength();
|
|
||||||
}
|
|
||||||
size_t len_addon= get_record_max_affix_length() +
|
|
||||||
get_max_key_addon_space_per_record();
|
|
||||||
len+= len_addon;
|
|
||||||
len_last+= len_addon;
|
|
||||||
size_t min_sz= len*(min_records-1) + len_last;
|
|
||||||
min_sz+= pack_length_with_blob_ptrs;
|
|
||||||
size_t add_sz= 0;
|
|
||||||
for (uint i=0; i < min_records; i++)
|
|
||||||
add_sz+= join_tab_scan->aux_buffer_incr(i+1);
|
|
||||||
avg_aux_buffer_incr= add_sz/min_records;
|
|
||||||
min_sz+= add_sz;
|
|
||||||
set_if_bigger(min_sz, 1);
|
|
||||||
min_buff_size= min_sz;
|
|
||||||
}
|
}
|
||||||
|
len_addon= (get_record_max_affix_length() +
|
||||||
|
get_max_key_addon_space_per_record());
|
||||||
|
len+= len_addon;
|
||||||
|
len_last+= len_addon;
|
||||||
|
min_sz= len*(min_records-1) + len_last;
|
||||||
|
min_sz+= pack_length_with_blob_ptrs;
|
||||||
|
for (uint i=0; i < min_records; i++)
|
||||||
|
add_sz+= join_tab_scan->aux_buffer_incr(i+1);
|
||||||
|
avg_aux_buffer_incr= add_sz/min_records;
|
||||||
|
min_sz+= add_sz;
|
||||||
|
set_if_bigger(min_sz, 1);
|
||||||
|
min_buff_size= min_sz;
|
||||||
return min_buff_size;
|
return min_buff_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -822,48 +827,48 @@ size_t JOIN_CACHE::get_min_join_buffer_size()
|
|||||||
The maximum possible size of the join buffer of this cache
|
The maximum possible size of the join buffer of this cache
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
|
size_t JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size,
|
||||||
|
size_t min_sz)
|
||||||
{
|
{
|
||||||
if (!max_buff_size)
|
if (max_buff_size)
|
||||||
|
return max_buff_size; // use cached value
|
||||||
|
|
||||||
|
size_t limit_sz= (size_t) join->thd->variables.join_buff_size;
|
||||||
|
|
||||||
|
if (!optimize_buff_size)
|
||||||
|
return max_buff_size= limit_sz;
|
||||||
|
|
||||||
|
size_t max_sz;
|
||||||
|
size_t len= 0;
|
||||||
|
double max_records, partial_join_cardinality=
|
||||||
|
(join_tab-1)->get_partial_join_cardinality();
|
||||||
|
/* Expected join buffer space used for one record */
|
||||||
|
size_t space_per_record;
|
||||||
|
|
||||||
|
for (JOIN_TAB *tab= start_tab; tab != join_tab;
|
||||||
|
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||||
{
|
{
|
||||||
size_t max_sz;
|
len+= tab->get_used_fieldlength();
|
||||||
size_t min_sz= get_min_join_buffer_size();
|
|
||||||
size_t len= 0;
|
|
||||||
double max_records, partial_join_cardinality=
|
|
||||||
(join_tab-1)->get_partial_join_cardinality();
|
|
||||||
size_t limit_sz= (size_t) join->thd->variables.join_buff_size;
|
|
||||||
/* Expected join buffer space used for one record */
|
|
||||||
size_t space_per_record;
|
|
||||||
|
|
||||||
for (JOIN_TAB *tab= start_tab; tab != join_tab;
|
|
||||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
|
||||||
{
|
|
||||||
len+= tab->get_used_fieldlength();
|
|
||||||
}
|
|
||||||
len+= get_record_max_affix_length();
|
|
||||||
avg_record_length= len;
|
|
||||||
len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
|
|
||||||
space_per_record= len;
|
|
||||||
|
|
||||||
/* Note that space_per_record can be 0 if no table fields where used */
|
|
||||||
max_records= (double) (limit_sz / MY_MAX(space_per_record, 1));
|
|
||||||
set_if_smaller(max_records, partial_join_cardinality);
|
|
||||||
set_if_bigger(max_records, 10.0);
|
|
||||||
|
|
||||||
if (!optimize_buff_size)
|
|
||||||
max_sz= limit_sz;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((size_t) (limit_sz / max_records) > space_per_record)
|
|
||||||
max_sz= space_per_record * (size_t) max_records;
|
|
||||||
else
|
|
||||||
max_sz= limit_sz;
|
|
||||||
max_sz+= pack_length_with_blob_ptrs;
|
|
||||||
set_if_smaller(max_sz, limit_sz);
|
|
||||||
}
|
|
||||||
set_if_bigger(max_sz, min_sz);
|
|
||||||
max_buff_size= max_sz;
|
|
||||||
}
|
}
|
||||||
|
len+= get_record_max_affix_length();
|
||||||
|
avg_record_length= len;
|
||||||
|
len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
|
||||||
|
space_per_record= len;
|
||||||
|
|
||||||
|
/* Note that space_per_record can be 0 if no table fields where used */
|
||||||
|
max_records= (double) (limit_sz / MY_MAX(space_per_record, 1));
|
||||||
|
set_if_smaller(max_records, partial_join_cardinality);
|
||||||
|
set_if_bigger(max_records, 10.0);
|
||||||
|
|
||||||
|
if ((size_t) (limit_sz / max_records) > space_per_record)
|
||||||
|
max_sz= space_per_record * (size_t) max_records;
|
||||||
|
else
|
||||||
|
max_sz= limit_sz;
|
||||||
|
max_sz+= pack_length_with_blob_ptrs;
|
||||||
|
set_if_smaller(max_sz, limit_sz);
|
||||||
|
|
||||||
|
set_if_bigger(max_sz, min_sz);
|
||||||
|
max_buff_size= max_sz;
|
||||||
return max_buff_size;
|
return max_buff_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,11 +911,7 @@ int JOIN_CACHE::alloc_buffer()
|
|||||||
bool optimize_buff_size=
|
bool optimize_buff_size=
|
||||||
optimizer_flag(join->thd, OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE);
|
optimizer_flag(join->thd, OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE);
|
||||||
buff= NULL;
|
buff= NULL;
|
||||||
min_buff_size= 0;
|
buff_size= get_max_join_buffer_size(optimize_buff_size, min_buff_size);
|
||||||
max_buff_size= 0;
|
|
||||||
min_records= 1;
|
|
||||||
min_buff_size= get_min_join_buffer_size();
|
|
||||||
buff_size= get_max_join_buffer_size(optimize_buff_size);
|
|
||||||
|
|
||||||
for (tab= start_tab; tab!= join_tab;
|
for (tab= start_tab; tab!= join_tab;
|
||||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||||
@ -1093,18 +1094,19 @@ int JOIN_CACHE::init(bool for_explain)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check the possibility to read the access keys directly from the join buffer
|
Check the possibility to read the access keys directly from the join buffer
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
check_emb_key_usage()
|
check_emb_key_usage()
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
The function checks some conditions at which the key values can be read
|
The function checks some conditions at which the key values can be
|
||||||
directly from the join buffer. This is possible when the key values can be
|
read directly from the join buffer. This is possible when the key
|
||||||
composed by concatenation of the record fields stored in the join buffer.
|
values can be composed by concatenation of the record fields
|
||||||
Sometimes when the access key is multi-component the function has to re-order
|
stored in the join buffer. Sometimes when the access key is
|
||||||
the fields written into the join buffer to make keys embedded. If key
|
multi-component the function has to re-order the fields written
|
||||||
values for the key access are detected as embedded then 'use_emb_key'
|
into the join buffer to make keys embedded. If key values for the
|
||||||
is set to TRUE.
|
key access are detected as embedded then 'use_emb_key' is set to
|
||||||
|
TRUE.
|
||||||
|
|
||||||
EXAMPLE
|
EXAMPLE
|
||||||
Let table t2 has an index defined on the columns a,b . Let's assume also
|
Let table t2 has an index defined on the columns a,b . Let's assume also
|
||||||
@ -1257,7 +1259,7 @@ bool JOIN_CACHE::check_emb_key_usage()
|
|||||||
trailing spaces
|
trailing spaces
|
||||||
- significant part of fixed length fields that can have trailing spaces
|
- significant part of fixed length fields that can have trailing spaces
|
||||||
with the prepanded length
|
with the prepanded length
|
||||||
- data of non-blob variable length fields with the prepanded data length
|
- data of non-blob variable length fields with the prepanded data length
|
||||||
- blob data from blob fields with the prepanded data length
|
- blob data from blob fields with the prepanded data length
|
||||||
(5) record offset values for the data fields that are referred to from
|
(5) record offset values for the data fields that are referred to from
|
||||||
other caches
|
other caches
|
||||||
@ -1328,7 +1330,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
Check whether we won't be able to add any new record into the cache after
|
Check whether we won't be able to add any new record into the cache after
|
||||||
this one because the cache will be full. Set last_record to TRUE if it's so.
|
this one because the cache will be full. Set last_record to TRUE if it's so.
|
||||||
The assume that the cache will be full after the record has been written
|
The assume that the cache will be full after the record has been written
|
||||||
into it if either the remaining space of the cache is not big enough for the
|
into it if either the remaining space of the cache is not big enough for the
|
||||||
record's blob values or if there is a chance that not all non-blob fields
|
record's blob values or if there is a chance that not all non-blob fields
|
||||||
of the next record can be placed there.
|
of the next record can be placed there.
|
||||||
This function is called only in the case when there is enough space left in
|
This function is called only in the case when there is enough space left in
|
||||||
@ -1350,7 +1352,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Put a reference to the fields of the record that are stored in the previous
|
Put a reference to the fields of the record that are stored in the previous
|
||||||
cache if there is any. This reference is passed by the 'link' parameter.
|
cache if there is any. This reference is passed by the 'link' parameter.
|
||||||
*/
|
*/
|
||||||
if (prev_cache)
|
if (prev_cache)
|
||||||
{
|
{
|
||||||
|
@ -602,9 +602,10 @@ public:
|
|||||||
void set_join_buffer_size(size_t sz) { buff_size= sz; }
|
void set_join_buffer_size(size_t sz) { buff_size= sz; }
|
||||||
|
|
||||||
/* Get the minimum possible size of the cache join buffer */
|
/* Get the minimum possible size of the cache join buffer */
|
||||||
virtual size_t get_min_join_buffer_size();
|
size_t get_min_join_buffer_size();
|
||||||
/* Get the maximum possible size of the cache join buffer */
|
/* Get the maximum possible size of the cache join buffer */
|
||||||
virtual size_t get_max_join_buffer_size(bool optimize_buff_size);
|
size_t get_max_join_buffer_size(bool optimize_buff_size,
|
||||||
|
size_t min_buffer_size_arg);
|
||||||
|
|
||||||
/* Shrink the size if the cache join buffer in a given ratio */
|
/* Shrink the size if the cache join buffer in a given ratio */
|
||||||
bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);
|
bool shrink_join_buffer_in_ratio(ulonglong n, ulonglong d);
|
||||||
|
Reference in New Issue
Block a user