1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00
- Post-review fixes. Intermediate commit to address review point 1.6.
- Fixed valgrind warnings
This commit is contained in:
unknown
2010-12-23 17:33:00 +02:00
parent 0bee625fea
commit 2e42948ed3
3 changed files with 72 additions and 48 deletions

View File

@@ -3653,8 +3653,8 @@ bool JOIN::optimize_unflattened_subqueries()
*/
bool JOIN::choose_subquery_plan(table_map join_tables)
{ /* The original QEP of the subquery. */
Query_plan_state save_qep;
{
Query_plan_state save_qep; /* The original QEP of the subquery. */
enum_reopt_result reopt_result= REOPT_NONE;
Item_in_subselect *in_subs;
@@ -3681,32 +3681,50 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
if (in_subs->in_strategy & SUBS_MATERIALIZATION &&
in_subs->in_strategy & SUBS_IN_TO_EXISTS)
{
JOIN *outer_join= unit->outer_select() ? unit->outer_select()->join : NULL;
JOIN *outer_join;
JOIN *inner_join= this;
/* Cost of the outer JOIN. */
double outer_read_time, outer_record_count;
/* Cost of the unmodified subquery. */
/* Number of (partial) rows of the outer JOIN filtered by the IN predicate. */
double outer_record_count;
/* Number of unique value combinations filtered by the IN predicate. */
double outer_lookup_keys;
/* Cost and row count of the unmodified subquery. */
double inner_read_time_1, inner_record_count_1;
/* Cost of the subquery with injected IN-EXISTS predicates. */
double inner_read_time_2, inner_record_count_2;
/* Cost and row count of the subquery with injected IN-EXISTS predicates. */
double inner_read_time_2;
/* The cost to compute IN via materialization. */
double materialize_strategy_cost;
/* The cost of the IN->EXISTS strategy. */
double in_exists_strategy_cost;
double dummy;
/*
A. Estimate the number of rows of the outer table that will be filtered
by the IN predicate.
*/
outer_join= unit->outer_select() ? unit->outer_select()->join : NULL;
if (outer_join)
{
uint outer_partial_plan_len;
/*
Make_cond_for_table is called for predicates only in the WHERE/ON
clauses. In all other cases, predicates are not pushed to any
JOIN_TAB, and their joi_tab_idx remains MAX_TABLES. Such predicates
are evaluated for each complete row.
are evaluated for each complete row of the outer join.
*/
uint partial_plan_len= (in_subs->get_join_tab_idx() == MAX_TABLES) ?
outer_join->tables :
in_subs->get_join_tab_idx() + 1;
outer_join->get_partial_join_cost(partial_plan_len,
&outer_read_time, &outer_record_count);
outer_partial_plan_len= (in_subs->get_join_tab_idx() == MAX_TABLES) ?
outer_join->tables :
in_subs->get_join_tab_idx() + 1;
outer_join->get_partial_join_cost(outer_partial_plan_len, &dummy,
&outer_record_count);
if (outer_join->tables > outer_join->const_tables)
outer_lookup_keys= prev_record_reads(outer_join->best_positions,
outer_partial_plan_len,
in_subs->used_tables());
else
{
/* If all tables are constant, positions is undefined. */
outer_lookup_keys= 1;
}
}
else
{
@@ -3714,15 +3732,17 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
TODO: outer_join can be NULL for DELETE statements.
How to compute its cost?
*/
outer_read_time= 1; /* TODO */
outer_record_count= 1; /* TODO */
outer_record_count= 1;
outer_lookup_keys=1;
}
DBUG_ASSERT(outer_lookup_keys <= outer_record_count);
inner_join->get_partial_join_cost(inner_join->tables,
&inner_read_time_1,
&inner_record_count_1);
/* inner_read_time_1 above is a dummy, get the correct total join cost. */
/*
B. Estimate the cost and number of records of the subquery both
unmodified, and with injected IN->EXISTS predicates.
*/
inner_read_time_1= inner_join->best_read;
inner_record_count_1= inner_join->record_count;
if (in_to_exists_where && const_tables != tables)
{
@@ -3734,9 +3754,6 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
if (reopt_result == REOPT_ERROR)
return TRUE;
inner_join->get_partial_join_cost(inner_join->tables,
&inner_read_time_2,
&inner_record_count_2);
/* inner_read_time_2 above is a dummy, get the correct total join cost. */
inner_read_time_2= inner_join->best_read;
@@ -3745,13 +3762,12 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
{
/* Reoptimization would not produce any better plan. */
inner_read_time_2= inner_read_time_1;
inner_record_count_2= inner_record_count_1;
}
/* Compute execution costs. */
/*
1. Compute the cost of the materialization strategy.
C. Compute execution costs.
*/
/* C.1 Compute the cost of the materialization strategy. */
uint rowlen= get_tmp_table_rec_length(unit->first_select()->item_list);
/* The cost of writing one row into the temporary table. */
double write_cost= get_tmp_table_write_cost(thd, inner_record_count_1,
@@ -3769,12 +3785,10 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
materialize_strategy_cost= materialization_cost +
outer_record_count * lookup_cost;
/*
2. Compute the cost of the IN=>EXISTS strategy.
*/
in_exists_strategy_cost= outer_record_count * inner_read_time_2;
/* C.2 Compute the cost of the IN=>EXISTS strategy. */
in_exists_strategy_cost= outer_lookup_keys * inner_read_time_2;
/* Compare the costs and choose the cheaper strategy. */
/* C.3 Compare the costs and choose the cheaper strategy. */
if (materialize_strategy_cost >= in_exists_strategy_cost)
in_subs->in_strategy&= ~SUBS_MATERIALIZATION;
else