Current Path : /usr/opt/mysql57/mysql-test/suite/opt_trace/include/ |
FreeBSD hs32.drive.ne.jp 9.1-RELEASE FreeBSD 9.1-RELEASE #1: Wed Jan 14 12:18:08 JST 2015 root@hs32.drive.ne.jp:/sys/amd64/compile/hs32 amd64 |
Current File : //usr/opt/mysql57/mysql-test/suite/opt_trace/include/subquery.inc |
# Test for optimizer tracing of subqueries --source include/have_optimizer_trace.inc --source include/have_64bit.inc SET optimizer_trace_max_mem_size=1048576; # 1MB SET end_markers_in_json=on; SET optimizer_trace="enabled=on,one_line=off"; CREATE TABLE t1 (a INT); CREATE TABLE t2 (a INT, b INT); INSERT INTO t1 VALUES (2); INSERT INTO t2 VALUES (1,7),(2,7); --echo # Subselect execute is traced every time it is executed SET @@optimizer_trace_features="greedy_search=off,repeated_subselect=on"; SELECT (SELECT a FROM t1 WHERE t1.a=t2.a), a FROM t2; --echo SELECT * FROM information_schema.OPTIMIZER_TRACE; --echo --echo # Subselect execute is traced only the first time it is executed SET @@optimizer_trace_features="greedy_search=off,repeated_subselect=off"; SELECT (SELECT a FROM t1 WHERE t1.a=t2.a), a FROM t2; --echo SELECT * FROM information_schema.OPTIMIZER_TRACE; --echo DROP TABLE t1,t2; SET @@optimizer_trace_features="default"; CREATE TABLE t1 (a FLOAT(5,4) zerofill); CREATE TABLE t2 (a FLOAT(5,4),b FLOAT(2,0)); # evaluate_subselect_cond_steps for build_equal_item() SELECT t1.a FROM t1 WHERE t1.a= (SELECT b FROM t2 LIMIT 1) AND NOT t1.a= (SELECT a FROM t2 LIMIT 1) ; --echo SELECT * FROM information_schema.OPTIMIZER_TRACE; --echo # evaluate_subselect_cond_steps for remove_eq_conds SELECT 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM t2 WHERE a = 50 AND b = 3); --echo SELECT * FROM information_schema.OPTIMIZER_TRACE; --echo # Distinct, order and group is removed from subquery. Note: For PS, # removal happens during prepare so the only visible effect is that # the subquery does not contain those clauses. SELECT 1 FROM DUAL WHERE NOT EXISTS (SELECT DISTINCT(a) FROM t2 GROUP BY a ORDER BY b); --echo SELECT * FROM information_schema.OPTIMIZER_TRACE; --echo DROP TABLE t1,t2; --echo # --echo # BUG#12905521 - ASSERT IN OPT_TRACE_STMT::SYNTAX_ERROR ON SELECT --echo # DISTINCT/MIN/JOIN/SUBQ QUERY --echo # CREATE TABLE t1 ( pk INTEGER, col_int_nokey INTEGER, col_int_key INTEGER, col_varchar_key VARCHAR(1), col_varchar_nokey VARCHAR(1), PRIMARY KEY (pk), KEY (col_varchar_key,col_int_key) ) ENGINE=MYISAM; CREATE TABLE t2 ( pk INTEGER, col_int_nokey INTEGER, col_int_key INTEGER, col_varchar_key VARCHAR(1), col_varchar_nokey VARCHAR(1), PRIMARY KEY (pk), KEY (col_varchar_key,col_int_key) ) ENGINE=MYISAM; CREATE TABLE t3 ( pk INTEGER, col_int_nokey INTEGER, col_int_key INTEGER, col_time_key TIME, col_datetime_nokey DATETIME, col_varchar_key VARCHAR(1), col_varchar_nokey VARCHAR(1), PRIMARY KEY (pk), KEY (col_time_key), KEY (col_varchar_key,col_int_key) ) ENGINE=MYISAM; CREATE TABLE t4 ( pk INTEGER, col_int_nokey INTEGER, col_int_key INTEGER, col_date_key DATE, col_date_nokey DATE, col_time_key TIME, col_time_nokey TIME, col_datetime_key DATETIME, col_datetime_nokey DATETIME, col_varchar_key VARCHAR(1), col_varchar_nokey VARCHAR(1), PRIMARY KEY (pk), KEY (col_varchar_key,col_int_key) ) ENGINE=MYISAM; INSERT IGNORE INTO t4 ( col_int_key,col_int_nokey, col_date_key,col_date_nokey, col_time_key,col_time_nokey, col_datetime_key,col_datetime_nokey, col_varchar_key,col_varchar_nokey ) VALUES (8,7,'2008-10-02','2008-10-02','04:07:22.028954','04:07:22.028954','2001-10-08 00:00:00','2001-10-08 00:00:00','g','g'); CREATE TABLE t5 ( pk INTEGER AUTO_INCREMENT, col_int_nokey INTEGER, col_int_key INTEGER, col_date_key DATE, col_date_nokey DATE, col_time_key TIME, col_time_nokey TIME, col_datetime_key DATETIME, col_datetime_nokey DATETIME, col_varchar_key VARCHAR(1), col_varchar_nokey VARCHAR(1), PRIMARY KEY (pk), KEY (col_int_key), KEY (col_varchar_key,col_int_key) ) ENGINE=MYISAM; INSERT INTO t5 ( col_int_key,col_int_nokey, col_date_key,col_date_nokey, col_time_key,col_time_nokey, col_datetime_key,col_datetime_nokey, col_varchar_key,col_varchar_nokey ) VALUES (8,NULL,'2000-12-03','2000-12-03','22:55:23.019225','22:55:23.019225','2005-07-20 00:00:00','2005-07-20 00:00:00','x','x'), (7,8,'2008-05-03','2008-05-03','10:19:31.050677','10:19:31.050677','2007-10-06 17:56:40.056051','2007-10-06 17:56:40.056051','d','d'), (8,6,'2000-09-20','2000-09-20','14:11:27.044095','14:11:27.044095','2003-06-13 23:19:49.018300','2003-06-13 23:19:49.018300','c','c'); set @old_opt_switch=@@optimizer_switch; if (`select locate('semijoin', @@optimizer_switch) > 0`) { --disable_query_log set optimizer_switch="semijoin=off"; --enable_query_log } select distinct alias1.`col_varchar_key` as field1 ,alias1.`col_date_key` as field2 ,( select min( sq1_alias1.`col_varchar_nokey` ) as sq1_field1 from ( t1 as sq1_alias1 inner join ( t5 as sq1_alias2 left join t5 as sq1_alias3 on (sq1_alias3.`col_varchar_nokey` = sq1_alias2.`col_varchar_key` ) ) on (sq1_alias3.`col_varchar_nokey` = sq1_alias2.`col_varchar_key` ) ) where exists ( select distinct c_sq1_alias2.`col_int_nokey` as c_sq1_field1 from ( t3 as c_sq1_alias1 right join t4 as c_sq1_alias2 on (c_sq1_alias2.`col_int_nokey` = c_sq1_alias1.`pk` ) ) where c_sq1_alias2.`col_varchar_key` = sq1_alias2.`col_varchar_nokey` ) ) as field3 ,( select max( sq2_alias1.`pk` ) as sq2_field1 from t5 as sq2_alias1 ) as field4 ,alias2.`col_varchar_nokey` as field5 ,alias2.`col_varchar_nokey` as field6 from ( t5 as alias1 right outer join ( ( ( select sq3_alias2.* from ( t5 as sq3_alias1 ,t4 as sq3_alias2 ) ) as alias2 right join t4 as alias3 on (alias3.`col_varchar_key` = alias2.`col_varchar_key` ) ) ) on (alias3.`col_int_key` = alias2.`pk` ) ) where ( alias1.`col_varchar_nokey` in ( select sq4_alias1.`col_varchar_key` as sq4_field1 from ( t3 as sq4_alias1 inner join ( t2 as sq4_alias2 right outer join t3 as sq4_alias3 on (sq4_alias3.`pk` = sq4_alias2.`col_int_key` ) ) on (sq4_alias3.`col_varchar_nokey` = sq4_alias2.`col_varchar_key` ) ) where sq4_alias2.`col_int_key` < alias1.`col_int_nokey` and sq4_alias3.`col_varchar_nokey` <> alias1.`col_varchar_key` ) ) and alias1.`col_int_key` not in (214) group by field1,field2,field3, field4,field5,field6; --replace_regex /("sort_buffer_size":) [0-9]+/\1 "NNN"/ select * from information_schema.optimizer_trace; set optimizer_switch=@old_opt_switch; drop table t1,t2,t3,t4,t5; --echo # --echo # BUG#12905758 - ASSERT IN OPT_TRACE_STMT::SYNTAX_ERROR ON --echo # SELECT/SUBQ/SUM QUERY --echo # CREATE TABLE t1 ( pk INTEGER AUTO_INCREMENT, col_int_nokey INTEGER, col_int_key INTEGER, col_date_key DATE, col_date_nokey DATE, col_time_key TIME, col_time_nokey TIME, col_datetime_key DATETIME, col_datetime_nokey DATETIME, col_varchar_key VARCHAR(1), col_varchar_nokey VARCHAR(1), PRIMARY KEY (pk), KEY (col_varchar_key,col_int_key) ) ENGINE=MYISAM; INSERT INTO t1 ( col_int_key,col_int_nokey, col_date_key,col_date_nokey, col_time_key,col_time_nokey, col_datetime_key,col_datetime_nokey, col_varchar_key,col_varchar_nokey ) VALUES (8,NULL,'2000-12-03','2000-12-03','22:55:23.019225','22:55:23.019225','2005-07-20 00:00:00','2005-07-20 00:00:00','x','x'), (8,6,'2000-09-20','2000-09-20','14:11:27.044095','14:11:27.044095','2003-06-13 23:19:49.018300','2003-06-13 23:19:49.018300','c','c'); CREATE TABLE t2 (I INTEGER); select ( select sum( subquery1_t1.`col_int_nokey` ) as subquery1_field1 from t1 as subquery1_t1 ) as field1 from ( t1 as table1 straight_join t1 as table2 on (table2.`col_varchar_key` = table1.`col_varchar_key` ) ) where ( table2.`col_int_nokey` <> any ( select 5 from t2 ) ) and table1.`pk` in (192,18) order by field1 desc; select * from information_schema.optimizer_trace; drop table t1,t2; --echo --echo # --echo # Tracing of semijoin loosescan --echo # --source include/show_json_object.inc create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, filler char(100), key(a,b)); insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B; create table t2 as select * from t1; set @old_opt_switch=@@optimizer_switch; set optimizer_switch="firstmatch=off,materialization=off,duplicateweedout=off"; set @old_opt_prune_level=@@optimizer_prune_level; set optimizer_prune_level=0; explain select * from t2 where a in (select b from t1 where a=3); --echo # Equality-propagation involving inner field => 1st sj equality is bound explain select * from t2 where (b+0,a+0) in (select a,b from t1 where a=3); --echo # Equality-propagation involving outer field => 3rd sj equality is bound. explain select * from t2 where (b,a,filler) in (select a,b,a*3 from t1) and filler='abc'; # Show that LS is possible (even though too costly in the end): SELECT show_json_object('"recalculate_access_paths_and_cost": {', TRACE) FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; --echo # Remove the condition on 'filler' => 3rd sj equality is not bound. explain select * from t2 where (b,a,filler) in (select a,b,a*3 from t1); # Show that LS is impossible: SELECT show_json_object('"searching_loose_scan_index": {', TRACE) FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; --echo # Equality-propagation involving outer field => 3rd sj equality is bound. explain select * from t2 as t3, t2 where t2.filler=t3.filler and (t2.b,t2.a,t2.filler) in (select a,b,a*3 from t1); SELECT show_json_object('"recalculate_access_paths_and_cost": {', TRACE) FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; --echo # In plan t3-t1-t2, 3rd outer expression is dependent only on --echo # previous tables => 3rd sj equality is bound. --echo # If t1 is before t3, 3rd sj equality is not bound. explain select * from t2 as t3 left join t2 on t2.filler+10=t3.filler+20 where (t2.b,t2.a,t3.filler+2) in (select a,b,a*3 from t1); # Show all LS plans (possible and impossible): SELECT show_json_object('"considered_execution_plans": [', TRACE) FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; drop table t0,t1,t2; --echo # --echo # Discover bound equality thanks to equality propagation --echo # specific of ON clause. --echo # CREATE TABLE t1 ( a int(11) DEFAULT NULL, b varchar(100) DEFAULT NULL, c int(11) DEFAULT NULL, KEY b_c_a (b,c,a) ) ENGINE=InnoDB; explain select * from t1 left join t1 as t2 on (t2.a= t1.a and (t2.a,t2.b) in (select a,b from t1 as t3)) where t1.a < 5; drop table t1; --echo # --echo # Show that loosescan planning is not dependent on order of --echo # creation of indexes anymore. --echo # create table it(a int, b int, index a_b (a,b), index a (a)) engine=InnoDB; insert into it values(1,1),(2,3),(4,3); let $query= select * from it as ot where (ot.a,ot.b) in (select it.a,it.b from it where it.b=3); eval $query; # The index on "A" is able to handle needed semi-join equalities, # because it handles the first one, and the second one is bound due to # b=3. let $read_trace= select TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' from information_schema.optimizer_trace; eval $read_trace; # Switch order of indexes: drop table it; create table it(a int, b int, index a (a),index a_b (a,b)) engine=InnoDB; insert into it values(1,1),(2,3),(4,3); eval $query; eval $read_trace; drop table it; --echo # --echo # Show that we reject LooseScan if no handled key parts --echo # CREATE TABLE t1 (a INT, b INT, KEY (a)) ENGINE=INNODB; CREATE TABLE t2 (a INT, b INT) ENGINE=INNODB; EXPLAIN SELECT * FROM t2 AS t3, t2 WHERE t2.b=t3.b AND (t2.b) IN (SELECT b*3 FROM t1 WHERE a=10); SELECT TRACE LIKE '%"some_index_part_used": false%' FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; DROP TABLE t1,t2; --echo # --echo # Show that we detect a hole in sequence of key parts --echo # CREATE TABLE ot1 (a INTEGER); INSERT INTO ot1 VALUES (0),(1),(3),(7); CREATE TABLE it1 (a VARCHAR(1), b INTEGER, KEY (a,b)); INSERT INTO it1 VALUES ('a',7), ('b',7); CREATE TABLE it2 (a VARCHAR(1), b INTEGER, KEY (a,b)); INSERT INTO it2 VALUES ('a',7), ('b',7); let $query= SELECT * FROM ot1 WHERE a IN ( SELECT it1.b FROM it1 JOIN it2 ON it1.a = it2.a ); eval explain $query; SELECT TRACE LIKE '%"index_can_remove_duplicates": false%' FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; DROP TABLE ot1, it1, it2; --echo # --echo # Show that handled keyparts cannot be on prefix --echo # create table t1 (a int, b varchar(100), key a_b (a,b)); insert into t1 values(25,'111111'),(25,'1111112'); let $query= select * from t1 as t2 where t2.b in (select b from t1 where a=25); eval explain $query; eval $query; alter table t1 drop key a_b, add key a_b_prefix (a,b(2)); eval explain $query; # If we had not detected that key is on prefix, result would be only 1 row: eval $query; select TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' from information_schema.optimizer_trace; drop table t1; set optimizer_switch=@old_opt_switch; set optimizer_prune_level=@old_opt_prune_level; drop function show_json_object;