Commit 4b24105d authored by Igor Babaev's avatar Igor Babaev

Introduced optimizer switch flag 'optimize_join_buffer_size'.

When this flag is 'off' the size of the used join buffer 
is taken directly from the system variable 'join_buffer_size'.
When this flag is 'on' then the size of the buffer depends
on the estimated number of rows in the partial join whose
records are to be stored in the buffer.
By default this flag is set 'on'.
parent 7e206872
This diff is collapsed.
...@@ -580,11 +580,12 @@ protected: ...@@ -580,11 +580,12 @@ protected:
#define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1<<16) #define OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL (1<<16)
#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1<<17) #define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1<<17)
#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1<<18) #define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1<<18)
#define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1<<19)
#ifdef DBUG_OFF #ifdef DBUG_OFF
# define OPTIMIZER_SWITCH_LAST (1<<19)
#else
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1<<19)
# define OPTIMIZER_SWITCH_LAST (1<<20) # define OPTIMIZER_SWITCH_LAST (1<<20)
#else
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1<<20)
# define OPTIMIZER_SWITCH_LAST (1<<21)
#endif #endif
#ifdef DBUG_OFF #ifdef DBUG_OFF
...@@ -605,7 +606,8 @@ protected: ...@@ -605,7 +606,8 @@ protected:
OPTIMIZER_SWITCH_SUBQUERY_CACHE | \ OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \ OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \ OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
OPTIMIZER_SWITCH_JOIN_CACHE_BKA) OPTIMIZER_SWITCH_JOIN_CACHE_BKA | \
OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE)
#else #else
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ # define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
...@@ -623,7 +625,8 @@ protected: ...@@ -623,7 +625,8 @@ protected:
OPTIMIZER_SWITCH_MRR_SORT_KEYS|\ OPTIMIZER_SWITCH_MRR_SORT_KEYS|\
OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \ OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \ OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
OPTIMIZER_SWITCH_JOIN_CACHE_BKA) OPTIMIZER_SWITCH_JOIN_CACHE_BKA | \
OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE)
#endif #endif
/* /*
......
...@@ -351,6 +351,7 @@ static const char *optimizer_switch_names[]= ...@@ -351,6 +351,7 @@ static const char *optimizer_switch_names[]=
"join_cache_incremental", "join_cache_incremental",
"join_cache_hashed", "join_cache_hashed",
"join_cache_bka", "join_cache_bka",
"optimize_join_buffer_size",
#ifndef DBUG_OFF #ifndef DBUG_OFF
"table_elimination", "table_elimination",
#endif #endif
...@@ -379,6 +380,7 @@ static const unsigned int optimizer_switch_names_len[]= ...@@ -379,6 +380,7 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("join_cache_incremental") - 1, sizeof("join_cache_incremental") - 1,
sizeof("join_cache_hashed") - 1, sizeof("join_cache_hashed") - 1,
sizeof("join_cache_bka") - 1, sizeof("join_cache_bka") - 1,
sizeof("optimize_join_buffer_size") - 1,
#ifndef DBUG_OFF #ifndef DBUG_OFF
sizeof("table_elimination") - 1, sizeof("table_elimination") - 1,
#endif #endif
...@@ -482,7 +484,8 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on," ...@@ -482,7 +484,8 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"mrr_sort_keys=on," "mrr_sort_keys=on,"
"join_cache_incremental=on," "join_cache_incremental=on,"
"join_cache_hashed=on," "join_cache_hashed=on,"
"join_cache_bka=on" "join_cache_bka=on,"
"optimize_join_buffer_size=on"
#ifndef DBUG_OFF #ifndef DBUG_OFF
",table_elimination=on"; ",table_elimination=on";
#else #else
...@@ -7115,7 +7118,7 @@ thread is in the relay logs.", ...@@ -7115,7 +7118,7 @@ thread is in the relay logs.",
"The limit of the space for all join buffers used by a query.", "The limit of the space for all join buffers used by a query.",
&global_system_variables.join_buff_space_limit, &global_system_variables.join_buff_space_limit,
&max_system_variables.join_buff_space_limit, 0, GET_ULL, &max_system_variables.join_buff_space_limit, 0, GET_ULL,
REQUIRED_ARG, 8*128*1024L, 2048+MALLOC_OVERHEAD, (longlong) ULONGLONG_MAX, REQUIRED_ARG, 16*128*1024L, 2048+MALLOC_OVERHEAD, (longlong) ULONGLONG_MAX,
MALLOC_OVERHEAD, 2048, 0}, MALLOC_OVERHEAD, 2048, 0},
{"join_cache_level", OPT_JOIN_CACHE_LEVEL, {"join_cache_level", OPT_JOIN_CACHE_LEVEL,
"Controls what join operations can be executed with join buffers. Odd numbers are used for plain join buffers while even numbers are used for linked buffers", "Controls what join operations can be executed with join buffers. Odd numbers are used for plain join buffers while even numbers are used for linked buffers",
......
...@@ -747,6 +747,7 @@ ulong JOIN_CACHE::get_min_join_buffer_size() ...@@ -747,6 +747,7 @@ ulong JOIN_CACHE::get_min_join_buffer_size()
avg_aux_buffer_incr= add_sz/min_records; avg_aux_buffer_incr= add_sz/min_records;
min_sz+= add_sz; min_sz+= add_sz;
min_sz+= pack_length_with_blob_ptrs; min_sz+= pack_length_with_blob_ptrs;
set_if_bigger(min_sz, 1);
min_buff_size= min_sz; min_buff_size= min_sz;
} }
return min_buff_size; return min_buff_size;
...@@ -759,16 +760,20 @@ ulong JOIN_CACHE::get_min_join_buffer_size() ...@@ -759,16 +760,20 @@ ulong JOIN_CACHE::get_min_join_buffer_size()
SYNOPSIS SYNOPSIS
get_max_join_buffer_size() get_max_join_buffer_size()
optimize_buff_size FALSE <-> do not take more memory than needed for
the estimated number of records in the partial join
DESCRIPTION DESCRIPTION
At the first its invocation for the cache the function calculates the At the first its invocation for the cache the function calculates the
maximum possible size of join buffer for the cache. This value does not maximum possible size of join buffer for the cache. If the parameter
exceed the estimate of the number of records 'max_records' in the partial optimize_buff_size true then this value does not exceed the size of the
join that joins tables from the first one through join_tab. This value space needed for the estimated number of records 'max_records' in the
is also capped off by the value of join_tab->join_buffer_size_limit, if it partial join that joins tables from the first one through join_tab. This
has been set a to non-zero value, and by the value of the system parameter value is also capped off by the value of join_tab->join_buffer_size_limit,
join_buffer_size - otherwise. After the calculation of the interesting size if it has been set a to non-zero value, and by the value of the system
the function saves the value in the field 'max_buff_size' in order to use parameter join_buffer_size - otherwise. After the calculation of the
it directly at the next invocations of the function. interesting size the function saves the value in the field 'max_buff_size'
in order to use it directly at the next invocations of the function.
NOTES NOTES
Currently the value of join_tab->join_buffer_size_limit is initialized Currently the value of join_tab->join_buffer_size_limit is initialized
...@@ -778,7 +783,7 @@ ulong JOIN_CACHE::get_min_join_buffer_size() ...@@ -778,7 +783,7 @@ ulong 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
*/ */
ulong JOIN_CACHE::get_max_join_buffer_size() ulong JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
{ {
if (!max_buff_size) if (!max_buff_size)
{ {
...@@ -795,12 +800,17 @@ ulong JOIN_CACHE::get_max_join_buffer_size() ...@@ -795,12 +800,17 @@ ulong JOIN_CACHE::get_max_join_buffer_size()
ulong limit_sz= join->thd->variables.join_buff_size; ulong limit_sz= join->thd->variables.join_buff_size;
if (join_tab->join_buffer_size_limit) if (join_tab->join_buffer_size_limit)
set_if_smaller(limit_sz, join_tab->join_buffer_size_limit); set_if_smaller(limit_sz, join_tab->join_buffer_size_limit);
if (!optimize_buff_size)
max_sz= limit_sz;
else
{
if (limit_sz / max_records > space_per_record) if (limit_sz / max_records > space_per_record)
max_sz= space_per_record * max_records; max_sz= space_per_record * max_records;
else else
max_sz= limit_sz; max_sz= limit_sz;
max_sz+= pack_length_with_blob_ptrs; max_sz+= pack_length_with_blob_ptrs;
set_if_smaller(max_sz, limit_sz); set_if_smaller(max_sz, limit_sz);
}
set_if_bigger(max_sz, min_sz); set_if_bigger(max_sz, min_sz);
max_buff_size= max_sz; max_buff_size= max_sz;
} }
...@@ -843,6 +853,8 @@ int JOIN_CACHE::alloc_buffer() ...@@ -843,6 +853,8 @@ int JOIN_CACHE::alloc_buffer()
ulonglong curr_min_buff_space_sz= 0; ulonglong curr_min_buff_space_sz= 0;
ulonglong join_buff_space_limit= ulonglong join_buff_space_limit=
join->thd->variables.join_buff_space_limit; join->thd->variables.join_buff_space_limit;
bool optimize_buff_size=
optimizer_flag(join->thd, OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE);
double partial_join_cardinality= (join_tab-1)->get_partial_join_cardinality(); double partial_join_cardinality= (join_tab-1)->get_partial_join_cardinality();
buff= NULL; buff= NULL;
min_buff_size= 0; min_buff_size= 0;
...@@ -852,7 +864,7 @@ int JOIN_CACHE::alloc_buffer() ...@@ -852,7 +864,7 @@ int JOIN_CACHE::alloc_buffer()
(ulonglong) partial_join_cardinality : join_buff_space_limit; (ulonglong) partial_join_cardinality : join_buff_space_limit;
set_if_bigger(max_records, 10); set_if_bigger(max_records, 10);
min_buff_size= get_min_join_buffer_size(); min_buff_size= get_min_join_buffer_size();
buff_size= get_max_join_buffer_size(); buff_size= get_max_join_buffer_size(optimize_buff_size);
for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++) for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++)
{ {
cache= tab->cache; cache= tab->cache;
...@@ -865,8 +877,9 @@ int JOIN_CACHE::alloc_buffer() ...@@ -865,8 +877,9 @@ int JOIN_CACHE::alloc_buffer()
if (curr_min_buff_space_sz > join_buff_space_limit || if (curr_min_buff_space_sz > join_buff_space_limit ||
(curr_buff_space_sz > join_buff_space_limit && (curr_buff_space_sz > join_buff_space_limit &&
(!optimize_buff_size ||
join->shrink_join_buffers(join_tab, curr_buff_space_sz, join->shrink_join_buffers(join_tab, curr_buff_space_sz,
join_buff_space_limit))) join_buff_space_limit))))
goto fail; goto fail;
for (ulong buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; ) for (ulong buff_size_decr= (buff_size-min_buff_size)/4 + 1; ; )
......
...@@ -583,7 +583,7 @@ public: ...@@ -583,7 +583,7 @@ public:
/* Get the minimum possible size of the cache join buffer */ /* Get the minimum possible size of the cache join buffer */
virtual ulong get_min_join_buffer_size(); virtual ulong 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 ulong get_max_join_buffer_size(); virtual ulong get_max_join_buffer_size(bool optimize_buff_size);
/* 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment