Commit aa551f1b authored by Sergey Petrunya's avatar Sergey Petrunya

Post-merge fixes part#2

parent f0038da8
......@@ -2831,7 +2831,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cac
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; FirstMatch(t1)
Warnings:
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`two` = `test`.`t1`.`two`) and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`flag` = 'N'))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
......@@ -3429,7 +3429,7 @@ AAA 8
EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1
DROP TABLE t1;
create table t1( f1 int,f2 int);
......
drop table if exists t1,t2,t3,t4,t5,t6;
#
# Bug #46791: Assertion failed:(table->key_read==0),function unknown
# function,file sql_base.cc
......@@ -735,6 +736,7 @@ WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 ));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 test.t1.f10 1
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary
SELECT * FROM t1
WHERE f3 = (
......@@ -749,6 +751,7 @@ WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 ));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 10 test.t1.f10,test.t1.f10 1
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary
SELECT * FROM t1
WHERE f3 = (
......
......@@ -961,7 +961,7 @@ FROM t1
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 105.00 Using where; FirstMatch(t2)
1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 100.00 Using where; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_key` = `test`.`t2`.`varchar_nokey`) and (`test`.`t1`.`varchar_nokey` = `test`.`t2`.`varchar_nokey`) and ((`test`.`t2`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
SELECT varchar_nokey
......
......@@ -33,7 +33,7 @@ a b
9 5
explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 3
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t1.a 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
select * from t2 where b in (select a from t1);
......@@ -53,7 +53,7 @@ insert into t3 select a,a, a,a,a from t0;
explain select * from t3 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL b NULL NULL NULL 10
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
......@@ -76,7 +76,7 @@ A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
from t0 A, t0 B where B.a <5;
explain select * from t3 where b in (select a from t0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
1 PRIMARY t3 ref b b 5 test.t0.a 1
2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
set @save_ecp= @@engine_condition_pushdown;
......@@ -103,7 +103,7 @@ set max_heap_table_size= @save_max_heap_table_size;
explain select * from t1 where a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
2 SUBQUERY t2 index b b 5 NULL 10 Using index
select * from t1;
a b
......@@ -131,7 +131,7 @@ explain select
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY it ALL NULL NULL NULL NULL 22
select
......@@ -165,7 +165,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2)
from t2 ot where a in (select a from t1 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot ALL NULL NULL NULL NULL 22
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
2 SUBQUERY it ALL NULL NULL NULL NULL 32
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -199,7 +199,7 @@ explain select
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
from t1 ot where a in (select a from t2 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 22
1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY it ALL NULL NULL NULL NULL 22
select
......@@ -233,7 +233,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2)
from t2 ot where a in (select a from t1 it);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot ALL NULL NULL NULL NULL 22
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
2 SUBQUERY it ALL NULL NULL NULL NULL 52
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -350,7 +350,7 @@ WHERE t1.Code IN (
SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
SELECT Name FROM t1
WHERE t1.Code IN (
......@@ -361,6 +361,10 @@ Canada
China
Czech Republic
drop table t1, t2;
drop procedure if exists p1;
drop procedure if exists p2;
drop procedure if exists p3;
drop procedure if exists p4;
CREATE TABLE t1(a INT);
CREATE TABLE t2(c INT);
CREATE PROCEDURE p1(v1 int)
......@@ -694,7 +698,7 @@ The following must use loose index scan over t3, key a:
explain select count(a) from t2 where a in ( SELECT a FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index a a 5 NULL 1000 Using index
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
2 SUBQUERY t3 index a a 5 NULL 30000 Using index
select count(a) from t2 where a in ( SELECT a FROM t3);
count(a)
......
......@@ -969,7 +969,7 @@ FROM t1
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 105.00 Using where; FirstMatch(t2); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 100.00 Using where; FirstMatch(t2); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
Warnings:
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_key` = `test`.`t2`.`varchar_nokey`) and (`test`.`t1`.`varchar_nokey` = `test`.`t2`.`varchar_nokey`) and ((`test`.`t2`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
SELECT varchar_nokey
......
drop table if exists t0, t1, t2, t3, t4;
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='materialization=on';
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 as select * from t0;
......@@ -40,14 +41,14 @@ explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
# Compare to this which really will have 50 record combinations:
explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 50 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
# Outer joins also work:
explain select * from t3
......@@ -55,7 +56,7 @@ where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 50 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using temporary
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
create table t4 (a int, b int, filler char(20), unique key(a,b));
insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B;
......@@ -65,7 +66,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY t4 ALL a NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t4.a 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B;
explain select * from t4 where
......@@ -75,9 +76,9 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
3 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
drop table t1,t2,t3,t4;
drop table t0;
......@@ -99,3 +100,4 @@ GROUP BY 1
);
f1
DROP TABLE t1, t2;
set optimizer_switch=@save_optimizer_switch;
......@@ -9,13 +9,6 @@ set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
--source t/subselect_sj_mat.test
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
explain select min(a1) from t1 where 7 in (select b1 from t2);
select min(a1) from t1 where 7 in (select b1 from t2);
# Executed via IN=>EXISTS
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
set @@optimizer_switch=default;
#
# Test that the contents of the temp table of a materialized subquery is
# cleaned up between PS re-executions.
......
......@@ -3,7 +3,6 @@
# (WL#1110: Subquery optimization: materialization)
#
set optimizer_switch='firstmatch=off';
--disable_warnings
drop table if exists t1, t2, t3, t1i, t2i, t3i;
drop view if exists v1, v2, v1m, v2m;
......@@ -48,6 +47,8 @@ insert into t1i select * from t1;
insert into t2i select * from t2;
insert into t3i select * from t3;
# force the use of materialization
set @@optimizer_switch='materialization=on,in_to_exists=off,firstmatch=off';
/******************************************************************************
* Simple tests.
......@@ -920,8 +921,8 @@ set session optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
#
# Test that the contentes of the temp table of a materialized subquery is
# cleanup up between PS reexecutions.
# Test that the contents of the temp table of a materialized subquery is
# cleaned up between PS re-executions.
#
create table t0 (a int);
......@@ -969,4 +970,3 @@ explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select subst
select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
drop table t1_1024, t2_1024;
......@@ -6,6 +6,7 @@ drop table if exists t0, t1, t2, t3, t4;
--enable_warnings
set @save_optimizer_switch=@@optimizer_switch;
set optimizer_switch='materialization=on';
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
......@@ -94,4 +95,5 @@ WHERE ( f1 ) IN (
);
DROP TABLE t1, t2;
set optimizer_switch=@save_optimizer_switch;
......@@ -353,7 +353,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
}
else
{
DBUG_PRINT("info", ("Subquery can't be converted to semi-join"));
DBUG_PRINT("info", ("Subquery can't be converted to merged semi-join"));
/* Test if the user has set a legal combination of optimizer switches. */
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_IN_TO_EXISTS) &&
!optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION))
......@@ -395,7 +395,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
join->sj_subselects list to be populated for every EXECUTE.
*/
if (!select_lex->is_part_of_union() && // 1
if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) &&
!select_lex->is_part_of_union() && // 1
parent_unit->first_select()->leaf_tables && // 2
thd->lex->sql_command == SQLCOM_SELECT && // *
select_lex->outer_select()->leaf_tables && // 2A
......@@ -888,8 +889,6 @@ void get_delayed_table_estimates(TABLE *table,
double *startup_cost)
{
Item_in_subselect *item= table->pos_in_table_list->jtbm_subselect;
double rows;
double read_time;
//psergey-merge: moving off here: item->optimize(&rows, &read_time);
......@@ -899,10 +898,11 @@ void get_delayed_table_estimates(TABLE *table,
subselect_hash_sj_engine *hash_sj_engine=
((subselect_hash_sj_engine*)item->engine);
*out_rows= (ha_rows)rows;
*startup_cost= read_time;
*out_rows= (ha_rows)item->jtbm_record_count;
*startup_cost= item->jtbm_read_time;
/* Calculate cost of scanning the temptable */
double data_size= rows * hash_sj_engine->tmp_table->s->reclength;
double data_size= (*out_rows) * hash_sj_engine->tmp_table->s->reclength;
/* Do like in handler::read_time */
*scan_time= data_size/IO_SIZE + 2;
}
......@@ -1326,6 +1326,9 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
// DBUG_RETURN(TRUE);
double rows;
double read_time;
// psergey-merge: disable IN->EXISTS for JTBM subqueries, for now.
subq_pred->in_strategy &= ~SUBS_IN_TO_EXISTS;
subq_pred->optimize(&rows, &read_time);
subq_pred->jtbm_read_time= read_time;
......@@ -1710,10 +1713,16 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
sjm->tables= n_tables;
sjm->is_used= FALSE;
double subjoin_out_rows, subjoin_read_time;
/*
join->get_partial_cost_and_fanout(n_tables + join->const_tables,
table_map(-1),
&subjoin_read_time,
&subjoin_out_rows);
*/
join->get_prefix_cost_and_fanout(n_tables,
&subjoin_read_time,
&subjoin_out_rows);
sjm->materialization_cost.convert_from_cost(subjoin_read_time);
sjm->rows= subjoin_out_rows;
......
......@@ -5935,6 +5935,36 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
}
/*
Get prefix cost and fanout. This function is different from
get_partial_cost_and_fanout:
- it operates on a JOIN that haven't yet finished its optimization phase (in
particular, fix_semijoin_strategies_for_picked_join_order() and
get_best_combination() haven't been called)
- it assumes the the join prefix doesn't have any semi-join plans
These assumptions are met by the caller of the function.
*/
void JOIN::get_prefix_cost_and_fanout(uint n_tables,
double *read_time_arg,
double *record_count_arg)
{
double record_count= 1;
double read_time= 0.0;
for (uint i= const_tables; i < n_tables + const_tables ; i++)
{
if (best_positions[i].records_read)
{
record_count *= best_positions[i].records_read;
read_time += best_positions[i].read_time;
}
}
*read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE;
*record_count_arg= record_count;
}
/**
Find a good, possibly optimal, query execution plan (QEP) by a possibly
exhaustive search.
......
......@@ -1138,12 +1138,13 @@ public:
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
}
bool choose_subquery_plan(table_map join_tables);
//void get_partial_join_cost(uint n_tables,
// double *read_time_arg, double *record_count_arg);
void get_partial_cost_and_fanout(uint end_tab_idx,
table_map filter_map,
double *read_time_arg,
double *record_count_arg);
void get_prefix_cost_and_fanout(uint n_tables,
double *read_time_arg,
double *record_count_arg);
private:
/**
TRUE if the query contains an aggregate function but has no GROUP
......
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