1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Merge mysql.com:/d2/hf/mrg/mysql-5.0-opt

into  mysql.com:/d2/hf/mrg/mysql-5.1-opt
This commit is contained in:
holyfoot/hf@hfmain.(none)
2007-05-31 14:23:45 +05:00
6 changed files with 126 additions and 38 deletions

View File

@ -49,15 +49,15 @@ static int sort_keyuse(KEYUSE *a,KEYUSE *b);
static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
table_map used_tables);
static void choose_plan(JOIN *join,table_map join_tables);
static bool choose_plan(JOIN *join,table_map join_tables);
static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
table_map remaining_tables, uint idx,
double record_count, double read_time);
static void optimize_straight_join(JOIN *join, table_map join_tables);
static void greedy_search(JOIN *join, table_map remaining_tables,
static bool greedy_search(JOIN *join, table_map remaining_tables,
uint depth, uint prune_level);
static void best_extension_by_limited_search(JOIN *join,
static bool best_extension_by_limited_search(JOIN *join,
table_map remaining_tables,
uint idx, double record_count,
double read_time, uint depth,
@ -69,7 +69,7 @@ static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
TODO: 'find_best' is here only temporarily until 'greedy_search' is
tested and approved.
*/
static void find_best(JOIN *join,table_map rest_tables,uint index,
static bool find_best(JOIN *join,table_map rest_tables,uint index,
double record_count,double read_time);
static uint cache_record_length(JOIN *join,uint index);
static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
@ -2755,7 +2755,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (join->const_tables != join->tables)
{
optimize_keyuse(join, keyuse_array);
choose_plan(join, all_table_map & ~join->const_table_map);
if (choose_plan(join, all_table_map & ~join->const_table_map))
DBUG_RETURN(TRUE);
}
else
{
@ -4404,11 +4405,12 @@ best_access_path(JOIN *join,
the array 'join->best_positions', and the cost of the plan in
'join->best_read'.
RETURN
None
RETURN VALUES
FALSE ok
TRUE Fatal error
*/
static void
static bool
choose_plan(JOIN *join, table_map join_tables)
{
uint search_depth= join->thd->variables.optimizer_search_depth;
@ -4441,14 +4443,16 @@ choose_plan(JOIN *join, table_map join_tables)
the greedy version. Will be removed when greedy_search is approved.
*/
join->best_read= DBL_MAX;
find_best(join, join_tables, join->const_tables, 1.0, 0.0);
if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
DBUG_RETURN(TRUE);
}
else
{
if (search_depth == 0)
/* Automatically determine a reasonable value for 'search_depth' */
search_depth= determine_search_depth(join);
greedy_search(join, join_tables, search_depth, prune_level);
if (greedy_search(join, join_tables, search_depth, prune_level))
DBUG_RETURN(TRUE);
}
}
@ -4456,7 +4460,7 @@ choose_plan(JOIN *join, table_map join_tables)
Store the cost of this query into a user variable
*/
join->thd->status_var.last_query_cost= join->best_read;
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
@ -4684,11 +4688,12 @@ optimize_straight_join(JOIN *join, table_map join_tables)
In the future, 'greedy_search' might be extended to support other
implementations of 'best_extension', e.g. some simpler quadratic procedure.
RETURN
None
RETURN VALUES
FALSE ok
TRUE Fatal error
*/
static void
static bool
greedy_search(JOIN *join,
table_map remaining_tables,
uint search_depth,
@ -4710,8 +4715,9 @@ greedy_search(JOIN *join,
do {
/* Find the extension of the current QEP with the lowest cost */
join->best_read= DBL_MAX;
best_extension_by_limited_search(join, remaining_tables, idx, record_count,
read_time, search_depth, prune_level);
if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
read_time, search_depth, prune_level))
DBUG_RETURN(TRUE);
if (size_remain <= search_depth)
{
@ -4722,7 +4728,7 @@ greedy_search(JOIN *join,
DBUG_EXECUTE("opt", print_plan(join, join->tables,
record_count, read_time, read_time,
"optimal"););
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
/* select the first table in the optimal extension as most promising */
@ -4867,11 +4873,12 @@ greedy_search(JOIN *join,
The parameter 'search_depth' provides control over the recursion
depth, and thus the size of the resulting optimal plan.
RETURN
None
RETURN VALUES
FALSE ok
TRUE Fatal error
*/
static void
static bool
best_extension_by_limited_search(JOIN *join,
table_map remaining_tables,
uint idx,
@ -4880,9 +4887,11 @@ best_extension_by_limited_search(JOIN *join,
uint search_depth,
uint prune_level)
{
DBUG_ENTER("best_extension_by_limited_search");
THD *thd= join->thd;
if (thd->killed) // Abort
return;
DBUG_RETURN(TRUE);
DBUG_ENTER("best_extension_by_limited_search");
DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx,
@ -4966,15 +4975,14 @@ best_extension_by_limited_search(JOIN *join,
if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
{ /* Recursively expand the current partial plan */
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
best_extension_by_limited_search(join,
remaining_tables & ~real_table_bit,
idx + 1,
current_record_count,
current_read_time,
search_depth - 1,
prune_level);
if (thd->killed)
DBUG_VOID_RETURN;
if (best_extension_by_limited_search(join,
remaining_tables & ~real_table_bit,
idx + 1,
current_record_count,
current_read_time,
search_depth - 1,
prune_level))
DBUG_RETURN(TRUE);
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
}
else
@ -5003,19 +5011,26 @@ best_extension_by_limited_search(JOIN *join,
restore_prev_nj_state(s);
}
}
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
/*
TODO: this function is here only temporarily until 'greedy_search' is
tested and accepted.
RETURN VALUES
FALSE ok
TRUE Fatal error
*/
static void
static bool
find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
double read_time)
{
DBUG_ENTER("find_best");
THD *thd= join->thd;
if (thd->killed)
DBUG_RETURN(TRUE);
if (!rest_tables)
{
DBUG_PRINT("best",("read_time: %g record_count: %g",read_time,
@ -5032,10 +5047,10 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
sizeof(POSITION)*idx);
join->best_read= read_time - 0.001;
}
return;
DBUG_RETURN(FALSE);
}
if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
return; /* Found better before */
DBUG_RETURN(FALSE); /* Found better before */
JOIN_TAB *s;
double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
@ -5068,10 +5083,9 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
best_read_time=current_read_time;
}
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
find_best(join,rest_tables & ~real_table_bit,idx+1,
current_record_count,current_read_time);
if (thd->killed)
return;
if (find_best(join,rest_tables & ~real_table_bit,idx+1,
current_record_count,current_read_time))
DBUG_RETURN(TRUE);
swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
}
restore_prev_nj_state(s);
@ -5079,6 +5093,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
break; // Don't test all combinations
}
}
DBUG_RETURN(FALSE);
}