diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2010-05-25 10:32:15 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2010-05-25 10:32:15 +0400 |
commit | 62bf7f61245cb1d50a8992a4a1b74df1074d77d3 (patch) | |
tree | e4c8e662276d97394a5a22c93a1adbafa0150ee9 /sql | |
parent | 5a53be655cd68878fbe8c8bc0a0c3c30aeb98c45 (diff) | |
download | mariadb-git-62bf7f61245cb1d50a8992a4a1b74df1074d77d3.tar.gz |
MWL#90: Subqueries: Inside-out execution for non-semijoin materialized subqueries that are AND-parts of the WHERE
- Code cleanu.
- Make MWL#90 code require @@optimizer_switch='semijoin=on'
- Update test results with the above
- Fork subselect_mat.test - we want to check both semi-join materialization,
which now has broader scope and non-semijoin materialization.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 35 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 |
3 files changed, 18 insertions, 23 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 22b36233e17..636cf3014a2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5761,32 +5761,27 @@ Item_field* Item_equal::get_first(Item_field *field) } else { -#if 0 /* The field is not in SJ-Materialization nest. We must return the first - field that's not embedded in a SJ-Materialization nest. - Example: suppose we have a join order: + field in the join order. The field may be inside a semi-join nest, i.e + a join order may look like this: SJ-Mat(it1 it2) ot1 ot2 - and equality ot2.col = ot1.col = it2.col - If we're looking for best substitute for 'ot2.col', we should pick ot1.col - and not it2.col, because when we run a join between ot1 and ot2 - execution of SJ-Mat(...) has already finished and we can't rely on the - value of it*.*. - psergey-fix-fix: ^^ THAT IS INCORRECT ^^. Pick the first, whatever that - is. + where we're looking what to substitute ot2.col for. In this case we must + still return it1.col, here's a proof why: + + First let's note that either it1.col or it2.col participates in + subquery's IN-equality. It can't be otherwise, because materialization is + only applicable to uncorrelated subqueries, so the only way we could + infer "it1.col=ot1.col" is from IN-equality. Ok, so IN-eqality has + it1.col or it2.col on its inner side. it1.col is first such item in the + join order, so it's not possible for SJ-Mat to be + SJ-Materialization-lookup, it is SJ-Materialization-Scan. The scan part + of this strategy will unpack value of it1.col=it2.col into it1.col + (that's the first equal item inside the subquery), and we'll be able to + get it from there. qed. */ - while ((item= it++)) - { - TABLE_LIST *emb_nest= item->field->table->pos_in_table_list->embedding; - if (!emb_nest || !emb_nest->sj_mat_info || - !emb_nest->sj_mat_info->is_used) - { - return item; - } - } -#endif return fields.head(); } // Shouldn't get here. diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 99272519665..6683b6f39e8 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -237,7 +237,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join) with jtbm strategy */ if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION && - thd->thd_marker.emb_on_expr_nest == (TABLE_LIST*)0x1) + thd->thd_marker.emb_on_expr_nest == (TABLE_LIST*)0x1 && + optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN)) { in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest; in_subs->is_flattenable_semijoin= FALSE; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8d1b5f62c49..39f0798f8b2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4287,7 +4287,6 @@ best_access_path(JOIN *join, double tmp; ha_rows rec; bool best_uses_jbuf= FALSE; - Item_in_subselect* jtbm_subselect= s->table->pos_in_table_list->jtbm_subselect; Loose_scan_opt loose_scan_opt; DBUG_ENTER("best_access_path"); @@ -4696,7 +4695,7 @@ best_access_path(JOIN *join, !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3) !(s->table->force_index && best_key && !s->quick) && // (4) - !(best_key && jtbm_subselect)) // (5) + !(best_key && s->table->pos_in_table_list->jtbm_subselect)) // (5) { // Check full join ha_rows rnd_records= s->found_records; /* |