1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-26301 Split optimization refills temporary table too many times

This patch optimizes the number of refills for the lateral derived table
to which a materialized derived table subject to split optimization is
is converted. This optimized number of refills is now considered as the
expected number of refills of the materialized derived table when searching
for the best possible splitting of the table.
This commit is contained in:
Igor Babaev
2023-05-02 23:17:07 -07:00
committed by Oleksandr Byelkin
parent ec79f37718
commit ce7ffe61d8
5 changed files with 910 additions and 32 deletions

View File

@ -7298,6 +7298,7 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
join->positions[idx].records_read=1.0; /* This is a const table */
join->positions[idx].cond_selectivity= 1.0;
join->positions[idx].ref_depend_map= 0;
join->positions[idx].partial_join_cardinality= 1;
// join->positions[idx].loosescan_key= MAX_KEY; /* Not a LooseScan */
join->positions[idx].sj_strategy= SJ_OPT_NONE;
@ -7315,6 +7316,7 @@ void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
}
join->best_ref[idx]=table;
join->positions[idx].spl_plan= 0;
join->positions[idx].spl_pd_boundary= 0;
}
@ -7431,6 +7433,7 @@ best_access_path(JOIN *join,
MY_BITMAP *eq_join_set= &s->table->eq_join_set;
KEYUSE *hj_start_key= 0;
SplM_plan_info *spl_plan= 0;
table_map spl_pd_boundary= 0;
Range_rowid_filter_cost_info *filter= 0;
const char* cause= NULL;
enum join_type best_type= JT_UNKNOWN, type= JT_UNKNOWN;
@ -7448,7 +7451,9 @@ best_access_path(JOIN *join,
loose_scan_opt.init(join, s, remaining_tables);
if (s->table->is_splittable())
spl_plan= s->choose_best_splitting(record_count, remaining_tables);
spl_plan= s->choose_best_splitting(idx,
remaining_tables,
&spl_pd_boundary);
if (s->keyuse)
{ /* Use key if possible */
@ -8243,8 +8248,9 @@ best_access_path(JOIN *join,
best_filter= filter;
/* range/index_merge/ALL/index access method are "independent", so: */
best_ref_depends_map= 0;
best_uses_jbuf= MY_TEST(!disable_jbuf && !((s->table->map &
join->outer_join)));
best_uses_jbuf= MY_TEST(!disable_jbuf &&
(join->allowed_outer_join_with_cache ||
!(s->table->map & join->outer_join)));
spl_plan= 0;
best_type= type;
}
@ -8266,6 +8272,7 @@ best_access_path(JOIN *join,
pos->loosescan_picker.loosescan_key= MAX_KEY;
pos->use_join_buffer= best_uses_jbuf;
pos->spl_plan= spl_plan;
pos->spl_pd_boundary= !spl_plan ? 0 : spl_pd_boundary;
pos->range_rowid_filter_info= best_filter;
loose_scan_opt.save_to_position(s, loose_scan_pos);
@ -8795,6 +8802,9 @@ optimize_straight_join(JOIN *join, table_map join_tables)
pushdown_cond_selectivity= table_cond_selectivity(join, idx, s,
join_tables);
position->cond_selectivity= pushdown_cond_selectivity;
double partial_join_cardinality= record_count *
pushdown_cond_selectivity;
join->positions[idx].partial_join_cardinality= partial_join_cardinality;
++idx;
}
@ -9833,6 +9843,8 @@ best_extension_by_limited_search(JOIN *join,
double partial_join_cardinality= current_record_count *
pushdown_cond_selectivity;
join->positions[idx].partial_join_cardinality= partial_join_cardinality;
if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) & allowed_tables )
{ /* Recursively expand the current partial plan */
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
@ -12860,6 +12872,9 @@ uint check_join_cache_usage(JOIN_TAB *tab,
join->return_tab= 0;
if (tab->no_forced_join_cache)
return 0;
/*
Don't use join cache if @@join_cache_level==0 or this table is the first
one join suborder (either at top level or inside a bush)
@ -13825,7 +13840,8 @@ bool JOIN_TAB::preread_init()
DBUG_RETURN(TRUE);
if (!(derived->get_unit()->uncacheable & UNCACHEABLE_DEPENDENT) ||
derived->is_nonrecursive_derived_with_rec_ref())
derived->is_nonrecursive_derived_with_rec_ref() ||
is_split_derived)
preread_init_done= TRUE;
if (select && select->quick)
select->quick->replace_handler(table->file);
@ -17276,6 +17292,9 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
reopt_remaining_tables &
~real_table_bit);
}
double partial_join_cardinality= rec_count *
pushdown_cond_selectivity;
join->positions[i].partial_join_cardinality= partial_join_cardinality;
(*outer_rec_count) *= pushdown_cond_selectivity;
if (!rs->emb_sj_nest)
*outer_rec_count= COST_MULT(*outer_rec_count, pos.records_read);
@ -20764,6 +20783,16 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
{
DBUG_ENTER("sub_select");
if (join_tab->split_derived_to_update && !end_of_records)
{
table_map tab_map= join_tab->split_derived_to_update;
for (uint i= 0; tab_map; i++, tab_map>>= 1)
{
if (tab_map & 1)
join->map2table[i]->preread_init_done= false;
}
}
if (join_tab->last_inner)
{
JOIN_TAB *last_inner_tab= join_tab->last_inner;