Commit 402e58cf authored by Sergey Petrunia's avatar Sergey Petrunia

MWL#17: Table elimination

- Do not show eliminated tables in the output of EXPLAIN EXTENDED
parent fd485ad9
...@@ -10,6 +10,11 @@ as select a, a as b from t1 where a in (1,3); ...@@ -10,6 +10,11 @@ as select a, a as b from t1 where a in (1,3);
explain select t1.a from t1 left join t2 on t2.a=t1.a; explain select t1.a from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 1 SIMPLE t1 ALL NULL NULL NULL NULL 4
explain extended select t1.a from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 1
select t1.a from t1 left join t2 on t2.a=t1.a; select t1.a from t1 left join t2 on t2.a=t1.a;
a a
0 0
...@@ -45,14 +50,16 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and ...@@ -45,14 +50,16 @@ explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 1 SIMPLE t1 ALL NULL NULL NULL NULL 4
# Elimination when done within an outer join nest: # Elimination when done within an outer join nest:
explain explain extended
select t0.* select t0.*
from from
t0 left join (t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and t0 left join (t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and
t3.a=t1.a) on t0.a=t1.a; t3.a=t1.a) on t0.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 4 1 SIMPLE t0 ALL NULL NULL NULL NULL 4 100.00
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
Warnings:
Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t0` left join (`test`.`t1`) on((`test`.`t0`.`a` = `test`.`t1`.`a`)) where 1
# Elimination with aggregate functions # Elimination with aggregate functions
explain select count(*) from t1 left join t2 on t2.a=t1.a; explain select count(*) from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
......
...@@ -17,6 +17,7 @@ create table t3 (a int primary key, b int) ...@@ -17,6 +17,7 @@ create table t3 (a int primary key, b int)
--echo # This will be eliminated: --echo # This will be eliminated:
explain select t1.a from t1 left join t2 on t2.a=t1.a; explain select t1.a from t1 left join t2 on t2.a=t1.a;
explain extended select t1.a from t1 left join t2 on t2.a=t1.a;
select t1.a from t1 left join t2 on t2.a=t1.a; select t1.a from t1 left join t2 on t2.a=t1.a;
...@@ -39,7 +40,7 @@ explain select t1.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a; ...@@ -39,7 +40,7 @@ explain select t1.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a;
explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and t3.a=t1.a; explain select t1.a from t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and t3.a=t1.a;
--echo # Elimination when done within an outer join nest: --echo # Elimination when done within an outer join nest:
explain explain extended
select t0.* select t0.*
from from
t0 left join (t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and t0 left join (t1 left join (t2 join t3 on t2.b=t3.b) on t2.a=t1.a and
......
...@@ -2386,6 +2386,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, ...@@ -2386,6 +2386,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
} }
else else
{ {
// psergey{
if (select_options & SELECT_DESCRIBE)
free_join= 0;
// }psergey
if (!(join= new JOIN(thd, fields, select_options, result))) if (!(join= new JOIN(thd, fields, select_options, result)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd_proc_info(thd, "init"); thd_proc_info(thd, "init");
...@@ -2523,7 +2527,7 @@ static void mark_table_as_eliminated(JOIN *join, TABLE *table, uint *const_tbl_c ...@@ -2523,7 +2527,7 @@ static void mark_table_as_eliminated(JOIN *join, TABLE *table, uint *const_tbl_c
{ {
DBUG_PRINT("info", ("Eliminated table %s", table->alias)); DBUG_PRINT("info", ("Eliminated table %s", table->alias));
tab->type= JT_CONST; tab->type= JT_CONST;
tab->eliminated= TRUE; join->eliminated_tables |= table->map;
*const_tables |= table->map; *const_tables |= table->map;
join->const_table_map|= table->map; join->const_table_map|= table->map;
set_position(join, (*const_tbl_count)++, tab, (KEYUSE*)0); set_position(join, (*const_tbl_count)++, tab, (KEYUSE*)0);
...@@ -2726,6 +2730,10 @@ static void eliminate_tables(JOIN *join, uint *const_tbl_count, table_map *const ...@@ -2726,6 +2730,10 @@ static void eliminate_tables(JOIN *join, uint *const_tbl_count, table_map *const
Item *item; Item *item;
table_map used_tables; table_map used_tables;
DBUG_ENTER("eliminate_tables"); DBUG_ENTER("eliminate_tables");
join->eliminated_tables= 0;
/* MWL#17 is only about outer join elimination, so: */
if (!join->outer_join) if (!join->outer_join)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -6060,6 +6068,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table) ...@@ -6060,6 +6068,7 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
tables= 1; tables= 1;
const_tables= 0; const_tables= 0;
const_table_map= 0; const_table_map= 0;
eliminated_tables= 0;
tmp_table_param.field_count= tmp_table_param.sum_func_count= tmp_table_param.field_count= tmp_table_param.sum_func_count=
tmp_table_param.func_count= 0; tmp_table_param.func_count= 0;
tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
...@@ -16509,7 +16518,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -16509,7 +16518,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
quick_type= -1; quick_type= -1;
//psergey-todo: //psergey-todo:
if (tab->eliminated) if (table->map & join->eliminated_tables)
{ {
used_tables|=table->map; used_tables|=table->map;
continue; continue;
...@@ -16912,6 +16921,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ...@@ -16912,6 +16921,7 @@ bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
*/ */
static void print_join(THD *thd, static void print_join(THD *thd,
table_map eliminated_tables,
String *str, String *str,
List<TABLE_LIST> *tables, List<TABLE_LIST> *tables,
enum_query_type query_type) enum_query_type query_type)
...@@ -16927,12 +16937,22 @@ static void print_join(THD *thd, ...@@ -16927,12 +16937,22 @@ static void print_join(THD *thd,
*t= ti++; *t= ti++;
DBUG_ASSERT(tables->elements >= 1); DBUG_ASSERT(tables->elements >= 1);
(*table)->print(thd, str, query_type); //pserey:TODO check!
(*table)->print(thd, eliminated_tables, str, query_type);
TABLE_LIST **end= table + tables->elements; TABLE_LIST **end= table + tables->elements;
for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++) for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
{ {
TABLE_LIST *curr= *tbl; TABLE_LIST *curr= *tbl;
// psergey-todo-todo:
// base table: check
if (curr->table && (curr->table->map & eliminated_tables) ||
curr->nested_join && !(curr->nested_join->used_tables &
~eliminated_tables))
{
continue;
}
if (curr->outer_join) if (curr->outer_join)
{ {
/* MySQL converts right to left joins */ /* MySQL converts right to left joins */
...@@ -16942,7 +16962,7 @@ static void print_join(THD *thd, ...@@ -16942,7 +16962,7 @@ static void print_join(THD *thd,
str->append(STRING_WITH_LEN(" straight_join ")); str->append(STRING_WITH_LEN(" straight_join "));
else else
str->append(STRING_WITH_LEN(" join ")); str->append(STRING_WITH_LEN(" join "));
curr->print(thd, str, query_type); curr->print(thd, eliminated_tables, str, query_type);
if (curr->on_expr) if (curr->on_expr)
{ {
str->append(STRING_WITH_LEN(" on(")); str->append(STRING_WITH_LEN(" on("));
...@@ -16996,12 +17016,13 @@ Index_hint::print(THD *thd, String *str) ...@@ -16996,12 +17016,13 @@ Index_hint::print(THD *thd, String *str)
@param str string where table should be printed @param str string where table should be printed
*/ */
void TABLE_LIST::print(THD *thd, String *str, enum_query_type query_type) void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
enum_query_type query_type)
{ {
if (nested_join) if (nested_join)
{ {
str->append('('); str->append('(');
print_join(thd, str, &nested_join->join_list, query_type); print_join(thd, eliminated_tables, str, &nested_join->join_list, query_type);
str->append(')'); str->append(')');
} }
else else
...@@ -17143,7 +17164,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type) ...@@ -17143,7 +17164,7 @@ void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
{ {
str->append(STRING_WITH_LEN(" from ")); str->append(STRING_WITH_LEN(" from "));
/* go through join tree */ /* go through join tree */
print_join(thd, str, &top_join_list, query_type); print_join(thd, join->eliminated_tables, str, &top_join_list, query_type);
} }
else if (where) else if (where)
{ {
......
...@@ -211,9 +211,6 @@ typedef struct st_join_table { ...@@ -211,9 +211,6 @@ typedef struct st_join_table {
/** Bitmap of nested joins this table is part of */ /** Bitmap of nested joins this table is part of */
nested_join_map embedding_map; nested_join_map embedding_map;
//psergey-todo: more justified place
bool eliminated;
void cleanup(); void cleanup();
inline bool is_using_loose_index_scan() inline bool is_using_loose_index_scan()
{ {
...@@ -289,6 +286,8 @@ public: ...@@ -289,6 +286,8 @@ public:
*/ */
bool resume_nested_loop; bool resume_nested_loop;
table_map const_table_map,found_const_table_map; table_map const_table_map,found_const_table_map;
table_map eliminated_tables;
/* /*
Bitmap of all inner tables from outer joins Bitmap of all inner tables from outer joins
*/ */
......
...@@ -1366,7 +1366,8 @@ struct TABLE_LIST ...@@ -1366,7 +1366,8 @@ struct TABLE_LIST
return (derived || view || schema_table || (create && !table->db_stat) || return (derived || view || schema_table || (create && !table->db_stat) ||
!table); !table);
} }
void print(THD *thd, String *str, enum_query_type query_type); void print(THD *thd, table_map eliminated_tables, String *str,
enum_query_type query_type);
bool check_single_table(TABLE_LIST **table, table_map map, bool check_single_table(TABLE_LIST **table, table_map map,
TABLE_LIST *view); TABLE_LIST *view);
bool set_insert_values(MEM_ROOT *mem_root); bool set_insert_values(MEM_ROOT *mem_root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment