Fixes lp:941889 "JOIN constructors takes a long time in 5.3"
- Remove all references of MAX_TABLES from JOIN struct and make these dynamic - Updated Join_plan_state to allocate just as many elements as it's needed sql/opt_subselect.cc: Optimized version of Join_plan_state sql/sql_select.cc: Set join->positions and join->best_positions dynamicly Don't call update_virtual_fields() if table->vfield is not set. sql/sql_select.h: Remove all references of MAX_TABLES from JOIN struct and Join_plan_state and make these dynamic
This commit is contained in:
parent
de1765fb64
commit
8e825a2249
@ -4961,7 +4961,8 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
|
||||
DBUG_ASSERT(!in_to_exists_where || in_to_exists_where->fixed);
|
||||
DBUG_ASSERT(!in_to_exists_having || in_to_exists_having->fixed);
|
||||
|
||||
Join_plan_state save_qep; /* The original QEP of the subquery. */
|
||||
/* The original QEP of the subquery. */
|
||||
Join_plan_state save_qep(table_count);
|
||||
|
||||
/*
|
||||
Compute and compare the costs of materialization and in-exists if both
|
||||
|
@ -3046,12 +3046,11 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
key_map const_ref, eq_part;
|
||||
bool has_expensive_keyparts;
|
||||
TABLE **table_vector;
|
||||
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
|
||||
JOIN_TAB *stat,*stat_end,*s,**stat_ref, **stat_vector;
|
||||
KEYUSE *keyuse,*start_keyuse;
|
||||
table_map outer_join=0;
|
||||
table_map no_rows_const_tables= 0;
|
||||
SARGABLE_PARAM *sargables= 0;
|
||||
JOIN_TAB *stat_vector[MAX_TABLES+1];
|
||||
List_iterator<TABLE_LIST> ti(tables_list);
|
||||
TABLE_LIST *tables;
|
||||
DBUG_ENTER("make_join_statistics");
|
||||
@ -3060,9 +3059,19 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
||||
table_count=join->table_count;
|
||||
|
||||
stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*(table_count));
|
||||
stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
|
||||
stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*
|
||||
(MAX_TABLES + table_count + 1));
|
||||
stat_vector= stat_ref + MAX_TABLES;
|
||||
table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
|
||||
if (!stat || !stat_ref || !table_vector)
|
||||
join->positions= new (join->thd->mem_root) POSITION[(table_count+1)];
|
||||
/*
|
||||
best_positions is ok to allocate with alloc() as we copy things to it with
|
||||
memcpy()
|
||||
*/
|
||||
join->best_positions= (POSITION*) join->thd->alloc(sizeof(POSITION)*
|
||||
(table_count +1));
|
||||
|
||||
if (join->thd->is_fatal_error)
|
||||
DBUG_RETURN(1); // Eom /* purecov: inspected */
|
||||
|
||||
join->best_ref=stat_vector;
|
||||
@ -15927,7 +15936,8 @@ join_read_system(JOIN_TAB *tab)
|
||||
empty_record(table); // Make empty record
|
||||
return -1;
|
||||
}
|
||||
update_virtual_fields(tab->join->thd, table);
|
||||
if (table->vfield)
|
||||
update_virtual_fields(tab->join->thd, table);
|
||||
store_record(table,record[1]);
|
||||
}
|
||||
else if (!table->status) // Only happens with left join
|
||||
@ -15976,7 +15986,8 @@ join_read_const(JOIN_TAB *tab)
|
||||
return report_error(table, error);
|
||||
return -1;
|
||||
}
|
||||
update_virtual_fields(tab->join->thd, table);
|
||||
if (table->vfield)
|
||||
update_virtual_fields(tab->join->thd, table);
|
||||
store_record(table,record[1]);
|
||||
}
|
||||
else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
|
||||
|
@ -742,7 +742,7 @@ public:
|
||||
Information about a position of table within a join order. Used in join
|
||||
optimization.
|
||||
*/
|
||||
typedef struct st_position
|
||||
typedef struct st_position :public Sql_alloc
|
||||
{
|
||||
/* The table that's put into join order */
|
||||
JOIN_TAB *table;
|
||||
@ -844,23 +844,36 @@ protected:
|
||||
*/
|
||||
class Join_plan_state {
|
||||
public:
|
||||
DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
|
||||
POSITION best_positions[MAX_TABLES+1]; /* Copy of JOIN::best_positions */
|
||||
DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
|
||||
POSITION *best_positions; /* Copy of JOIN::best_positions */
|
||||
/* Copies of the JOIN_TAB::keyuse pointers for each JOIN_TAB. */
|
||||
KEYUSE *join_tab_keyuse[MAX_TABLES];
|
||||
KEYUSE **join_tab_keyuse;
|
||||
/* Copies of JOIN_TAB::checked_keys for each JOIN_TAB. */
|
||||
key_map join_tab_checked_keys[MAX_TABLES];
|
||||
SJ_MATERIALIZATION_INFO *sj_mat_info[MAX_TABLES];
|
||||
key_map *join_tab_checked_keys;
|
||||
SJ_MATERIALIZATION_INFO **sj_mat_info;
|
||||
my_bool error;
|
||||
public:
|
||||
Join_plan_state()
|
||||
Join_plan_state(uint tables) : error(0)
|
||||
{
|
||||
keyuse.elements= 0;
|
||||
keyuse.buffer= NULL;
|
||||
best_positions= 0; /* To detect errors */
|
||||
error= my_multi_malloc(MYF(MY_WME),
|
||||
&best_positions,
|
||||
sizeof(*best_positions) * (tables + 1),
|
||||
&join_tab_keyuse,
|
||||
sizeof(*join_tab_keyuse) * tables,
|
||||
&join_tab_checked_keys,
|
||||
sizeof(*join_tab_checked_keys) * tables,
|
||||
&sj_mat_info,
|
||||
sizeof(sj_mat_info) * tables,
|
||||
NullS) == 0;
|
||||
}
|
||||
Join_plan_state(JOIN *join);
|
||||
~Join_plan_state()
|
||||
{
|
||||
delete_dynamic(&keyuse);
|
||||
my_free(best_positions, MYF(0));
|
||||
}
|
||||
};
|
||||
|
||||
@ -961,7 +974,7 @@ public:
|
||||
*/
|
||||
ha_rows fetch_limit;
|
||||
/* Finally picked QEP. This is result of join optimization */
|
||||
POSITION best_positions[MAX_TABLES+1];
|
||||
POSITION *best_positions;
|
||||
|
||||
/******* Join optimization state members start *******/
|
||||
/*
|
||||
@ -971,7 +984,7 @@ public:
|
||||
TABLE_LIST *emb_sjm_nest;
|
||||
|
||||
/* Current join optimization state */
|
||||
POSITION positions[MAX_TABLES+1];
|
||||
POSITION *positions;
|
||||
|
||||
/*
|
||||
Bitmap of nested joins embedding the position at the end of the current
|
||||
@ -1241,6 +1254,7 @@ public:
|
||||
exec_const_cond= 0;
|
||||
group_optimized_away= 0;
|
||||
no_rows_in_result_called= 0;
|
||||
positions= best_positions= 0;
|
||||
|
||||
all_fields= fields_arg;
|
||||
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
|
||||
|
Loading…
x
Reference in New Issue
Block a user