summaryrefslogtreecommitdiff
path: root/sql/opt_subselect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r--sql/opt_subselect.cc56
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);
}