diff options
Diffstat (limited to 'sql/opt_table_elimination.cc')
-rw-r--r-- | sql/opt_table_elimination.cc | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc index c204ee4e066..3958797ec44 100644 --- a/sql/opt_table_elimination.cc +++ b/sql/opt_table_elimination.cc @@ -31,6 +31,8 @@ #include "mariadb.h" #include "my_bit.h" #include "sql_select.h" +#include "opt_trace.h" +#include "my_json_writer.h" /* OVERVIEW @@ -522,7 +524,8 @@ eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list, table_map tables_in_list, Item *on_expr, - table_map tables_used_elsewhere); + table_map tables_used_elsewhere, + Json_writer_array* trace_eliminate_tables); static bool check_func_dependency(JOIN *join, table_map dep_tables, @@ -541,7 +544,8 @@ static Dep_module_expr *merge_eq_mods(Dep_module_expr *start, Dep_module_expr *new_fields, Dep_module_expr *end, uint and_level); -static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl); +static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl, + Json_writer_array* trace_eliminate_tables); static void add_module_expr(Dep_analysis_context *dac, Dep_module_expr **eq_mod, uint and_level, Dep_value_field *field_val, Item *right, @@ -608,6 +612,8 @@ void eliminate_tables(JOIN *join) if (!optimizer_flag(thd, OPTIMIZER_SWITCH_TABLE_ELIMINATION)) DBUG_VOID_RETURN; /* purecov: inspected */ + Json_writer_object trace_wrapper(thd); + /* Find the tables that are referred to from WHERE/HAVING */ used_tables= (join->conds? join->conds->used_tables() : 0) | (join->having? join->having->used_tables() : 0); @@ -617,12 +623,12 @@ void eliminate_tables(JOIN *join) we should also take into account tables mentioned in "val". */ if (join->thd->lex->sql_command == SQLCOM_INSERT_SELECT && - join->select_lex == &thd->lex->select_lex) + join->select_lex == thd->lex->first_select_lex()) { List_iterator<Item> val_it(thd->lex->value_list); while ((item= val_it++)) { - DBUG_ASSERT(item->fixed); + DBUG_ASSERT(item->is_fixed()); used_tables |= item->used_tables(); } } @@ -640,7 +646,7 @@ void eliminate_tables(JOIN *join) used_tables |= (*(cur_list->item))->used_tables(); } - if (join->select_lex == &thd->lex->select_lex) + if (join->select_lex == thd->lex->first_select_lex()) { /* Multi-table UPDATE: don't eliminate tables referred from SET statement */ @@ -663,13 +669,14 @@ void eliminate_tables(JOIN *join) } } } - + table_map all_tables= join->all_tables_map(); + Json_writer_array trace_eliminated_tables(thd,"eliminated_tables"); if (all_tables & ~used_tables) { /* There are some tables that we probably could eliminate. Try it. */ eliminate_tables_for_list(join, join->join_list, all_tables, NULL, - used_tables); + used_tables, &trace_eliminated_tables); } DBUG_VOID_RETURN; } @@ -712,7 +719,8 @@ void eliminate_tables(JOIN *join) static bool eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list, table_map list_tables, Item *on_expr, - table_map tables_used_elsewhere) + table_map tables_used_elsewhere, + Json_writer_array *trace_eliminate_tables) { TABLE_LIST *tbl; List_iterator<TABLE_LIST> it(*join_list); @@ -734,9 +742,10 @@ eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list, &tbl->nested_join->join_list, tbl->nested_join->used_tables, tbl->on_expr, - outside_used_tables)) + outside_used_tables, + trace_eliminate_tables)) { - mark_as_eliminated(join, tbl); + mark_as_eliminated(join, tbl, trace_eliminate_tables); } else all_eliminated= FALSE; @@ -748,7 +757,7 @@ eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list, check_func_dependency(join, tbl->table->map, NULL, tbl, tbl->on_expr)) { - mark_as_eliminated(join, tbl); + mark_as_eliminated(join, tbl, trace_eliminate_tables); } else all_eliminated= FALSE; @@ -1788,7 +1797,8 @@ Dep_module* Dep_value_field::get_next_unbound_module(Dep_analysis_context *dac, Mark one table or the whole join nest as eliminated. */ -static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl) +static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl, + Json_writer_array* trace_eliminate_tables) { TABLE *table; /* @@ -1801,7 +1811,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl) TABLE_LIST *child; List_iterator<TABLE_LIST> it(tbl->nested_join->join_list); while ((child= it++)) - mark_as_eliminated(join, child); + mark_as_eliminated(join, child, trace_eliminate_tables); } else if ((table= tbl->table)) { @@ -1812,6 +1822,7 @@ static void mark_as_eliminated(JOIN *join, TABLE_LIST *tbl) tab->type= JT_CONST; tab->table->const_table= 1; join->eliminated_tables |= table->map; + trace_eliminate_tables->add(table->alias.c_ptr_safe()); join->const_table_map|= table->map; set_position(join, join->const_tables++, tab, (KEYUSE*)0); } |