diff options
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r-- | sql/opt_subselect.cc | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 8493a8e4082..0add6db447a 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -30,6 +30,8 @@ 3.1.1 Merged semi-join TABLE_LIST object 3.1.2 Non-merged semi-join data structure 3.2 Semi-joins and query optimization + 3.2.1 Non-merged semi-joins and join optimization + 3.2.2 Merged semi-joins and join optimization 3.3 Semi-joins and query execution 1. What is a semi-join subquery @@ -99,8 +101,8 @@ 3. Code-level view of semi-join processing ------------------------------------------ - 3.1 Conversion - -------------- + 3.1 Conversion and pre-optimization data structures + --------------------------------------------------- * When doing JOIN::prepare for the subquery, we detect that it can be converted into a semi-join and register it in parent_join->sj_subselects @@ -117,7 +119,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Merged semi-join object is a TABLE_LIST that contains a sub-join of subquery tables and the semi-join ON expression (in this respect it is - ery similar to nested outer join representation) + very similar to nested outer join representation) Merged semi-join represents this SQL: ... SEMI JOIN (inner_tbl1 JOIN ... JOIN inner_tbl_n) ON sj_on_expr @@ -135,14 +137,38 @@ clause. (They do remain in PS-saved WHERE clause, and they replace themselves with Item_int(1) on subsequent re-executions). - 3.2 Semi-joins and query optimization - ------------------------------------- - Query optimizer operates on semi-join nests. + 3.2 Semi-joins and join optimization + ------------------------------------ + + 3.2.1 Non-merged semi-joins and join optimization + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + For join optimization purposes, non-merged semi-join nests are similar to + base tables - they've got one JOIN_TAB, which can be accessed with one of + two methods: + - full table scan (representing SJ-Materialization-Scan strategy) + - eq_ref-like table lookup (representing SJ-Materialization-Lookup) + + Unlike regular base tables, non-merged semi-joins have: + - non-zero JOIN_TAB::startup_cost, and + - join_tab->table->is_filled_at_execution()==TRUE, which means one + cannot do const table detection or range analysis or other table data- + dependent inferences + // instead, get_delayed_table_estimates() runs optimization on the nest so that + // we get an idea about temptable size + + 3.2.2 Merged semi-joins and join optimization + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - optimize_semijoin_nests() does pre-optimization + - during join optimization, the join has one JOIN_TAB (or is it POSITION?) + array, and suffix-based detection is used, see advance_sj_state() + - after join optimization is done, get_best_combination() switches + the data-structure to prefix-based, multiple JOIN_TAB ranges format. 3.3 Semi-joins and query execution ---------------------------------- * Join executor has hooks for all semi-join strategies. - TODO elaborate + TODO elaborate. + */ @@ -2682,8 +2708,6 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab) temptable. */ TABLE_REF *tab_ref; - //if (!(tab_ref= (TABLE_REF*) thd->alloc(sizeof(TABLE_REF)))) - // DBUG_RETURN(TRUE); /* purecov: inspected */ tab_ref= &sjm_tab->ref; tab_ref->key= 0; /* The only temp table index. */ tab_ref->key_length= tmp_key->key_length; @@ -3966,17 +3990,19 @@ static void remove_subq_pushed_predicates(JOIN *join, Item **where) pointers. RETURN - FALSE Ok - TRUE Error, join execution is not possible. + NESTED_LOOP_OK - OK + NESTED_LOOP_ERROR| NESTED_LOOP_KILLED - Error, abort the join execution */ -bool join_tab_execution_startup(JOIN_TAB *tab) +enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab) { Item_in_subselect *in_subs; DBUG_ENTER("join_tab_execution_startup"); + if (tab->table->pos_in_table_list && (in_subs= tab->table->pos_in_table_list->jtbm_subselect)) { + /* It's a non-merged SJM nest */ DBUG_ASSERT(in_subs->engine->engine_type() == subselect_engine::HASH_SJ_ENGINE); @@ -3988,13 +4014,13 @@ bool join_tab_execution_startup(JOIN_TAB *tab) hash_sj_engine->is_materialized= TRUE; if (hash_sj_engine->materialize_join->error || tab->join->thd->is_fatal_error) - DBUG_RETURN(TRUE); + DBUG_RETURN(NESTED_LOOP_ERROR); } } else if (tab->bush_children) { /* It's a merged SJM nest */ - int rc; // psergey3: todo: error codes! + enum_nested_loop_state rc; JOIN *join= tab->join; SJ_MATERIALIZATION_INFO *sjm= tab->bush_children->start->emb_sj_nest->sj_mat_info; JOIN_TAB *join_tab= tab->bush_children->start; @@ -4018,6 +4044,6 @@ bool join_tab_execution_startup(JOIN_TAB *tab) } } - DBUG_RETURN(0); + DBUG_RETURN(NESTED_LOOP_OK); } |