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_where || in_to_exists_where->fixed);
|
||||||
DBUG_ASSERT(!in_to_exists_having || in_to_exists_having->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
|
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;
|
key_map const_ref, eq_part;
|
||||||
bool has_expensive_keyparts;
|
bool has_expensive_keyparts;
|
||||||
TABLE **table_vector;
|
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;
|
KEYUSE *keyuse,*start_keyuse;
|
||||||
table_map outer_join=0;
|
table_map outer_join=0;
|
||||||
table_map no_rows_const_tables= 0;
|
table_map no_rows_const_tables= 0;
|
||||||
SARGABLE_PARAM *sargables= 0;
|
SARGABLE_PARAM *sargables= 0;
|
||||||
JOIN_TAB *stat_vector[MAX_TABLES+1];
|
|
||||||
List_iterator<TABLE_LIST> ti(tables_list);
|
List_iterator<TABLE_LIST> ti(tables_list);
|
||||||
TABLE_LIST *tables;
|
TABLE_LIST *tables;
|
||||||
DBUG_ENTER("make_join_statistics");
|
DBUG_ENTER("make_join_statistics");
|
||||||
@ -3060,9 +3059,19 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||||||
table_count=join->table_count;
|
table_count=join->table_count;
|
||||||
|
|
||||||
stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*(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));
|
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 */
|
DBUG_RETURN(1); // Eom /* purecov: inspected */
|
||||||
|
|
||||||
join->best_ref=stat_vector;
|
join->best_ref=stat_vector;
|
||||||
@ -15927,6 +15936,7 @@ join_read_system(JOIN_TAB *tab)
|
|||||||
empty_record(table); // Make empty record
|
empty_record(table); // Make empty record
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (table->vfield)
|
||||||
update_virtual_fields(tab->join->thd, table);
|
update_virtual_fields(tab->join->thd, table);
|
||||||
store_record(table,record[1]);
|
store_record(table,record[1]);
|
||||||
}
|
}
|
||||||
@ -15976,6 +15986,7 @@ join_read_const(JOIN_TAB *tab)
|
|||||||
return report_error(table, error);
|
return report_error(table, error);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (table->vfield)
|
||||||
update_virtual_fields(tab->join->thd, table);
|
update_virtual_fields(tab->join->thd, table);
|
||||||
store_record(table,record[1]);
|
store_record(table,record[1]);
|
||||||
}
|
}
|
||||||
|
@ -742,7 +742,7 @@ public:
|
|||||||
Information about a position of table within a join order. Used in join
|
Information about a position of table within a join order. Used in join
|
||||||
optimization.
|
optimization.
|
||||||
*/
|
*/
|
||||||
typedef struct st_position
|
typedef struct st_position :public Sql_alloc
|
||||||
{
|
{
|
||||||
/* The table that's put into join order */
|
/* The table that's put into join order */
|
||||||
JOIN_TAB *table;
|
JOIN_TAB *table;
|
||||||
@ -845,22 +845,35 @@ protected:
|
|||||||
class Join_plan_state {
|
class Join_plan_state {
|
||||||
public:
|
public:
|
||||||
DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
|
DYNAMIC_ARRAY keyuse; /* Copy of the JOIN::keyuse array. */
|
||||||
POSITION best_positions[MAX_TABLES+1]; /* Copy of JOIN::best_positions */
|
POSITION *best_positions; /* Copy of JOIN::best_positions */
|
||||||
/* Copies of the JOIN_TAB::keyuse pointers for each JOIN_TAB. */
|
/* 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. */
|
/* Copies of JOIN_TAB::checked_keys for each JOIN_TAB. */
|
||||||
key_map join_tab_checked_keys[MAX_TABLES];
|
key_map *join_tab_checked_keys;
|
||||||
SJ_MATERIALIZATION_INFO *sj_mat_info[MAX_TABLES];
|
SJ_MATERIALIZATION_INFO **sj_mat_info;
|
||||||
|
my_bool error;
|
||||||
public:
|
public:
|
||||||
Join_plan_state()
|
Join_plan_state(uint tables) : error(0)
|
||||||
{
|
{
|
||||||
keyuse.elements= 0;
|
keyuse.elements= 0;
|
||||||
keyuse.buffer= NULL;
|
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(JOIN *join);
|
||||||
~Join_plan_state()
|
~Join_plan_state()
|
||||||
{
|
{
|
||||||
delete_dynamic(&keyuse);
|
delete_dynamic(&keyuse);
|
||||||
|
my_free(best_positions, MYF(0));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -961,7 +974,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ha_rows fetch_limit;
|
ha_rows fetch_limit;
|
||||||
/* Finally picked QEP. This is result of join optimization */
|
/* Finally picked QEP. This is result of join optimization */
|
||||||
POSITION best_positions[MAX_TABLES+1];
|
POSITION *best_positions;
|
||||||
|
|
||||||
/******* Join optimization state members start *******/
|
/******* Join optimization state members start *******/
|
||||||
/*
|
/*
|
||||||
@ -971,7 +984,7 @@ public:
|
|||||||
TABLE_LIST *emb_sjm_nest;
|
TABLE_LIST *emb_sjm_nest;
|
||||||
|
|
||||||
/* Current join optimization state */
|
/* Current join optimization state */
|
||||||
POSITION positions[MAX_TABLES+1];
|
POSITION *positions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bitmap of nested joins embedding the position at the end of the current
|
Bitmap of nested joins embedding the position at the end of the current
|
||||||
@ -1241,6 +1254,7 @@ public:
|
|||||||
exec_const_cond= 0;
|
exec_const_cond= 0;
|
||||||
group_optimized_away= 0;
|
group_optimized_away= 0;
|
||||||
no_rows_in_result_called= 0;
|
no_rows_in_result_called= 0;
|
||||||
|
positions= best_positions= 0;
|
||||||
|
|
||||||
all_fields= fields_arg;
|
all_fields= fields_arg;
|
||||||
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
|
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user