diff --git a/mysql-test/r/explain_tree.result-pq b/mysql-test/r/explain_tree.result-pq index 4c833941dcc4..fca2d59a4661 100644 --- a/mysql-test/r/explain_tree.result-pq +++ b/mysql-test/r/explain_tree.result-pq @@ -691,9 +691,10 @@ test.t2 analyze status OK EXPLAIN format=tree SELECT * FROM t1 WHERE t1.i IN (SELECT t2.i FROM t2); EXPLAIN -> Parallel scan on - -> Nested loop inner join (cost=2.05 rows=4) - -> Filter: (t2.i is not null) (cost=0.65 rows=4) - -> PQblock scan on t2 using i1 (cost=0.65 rows=4) + -> Nested loop inner join + -> Remove duplicates from input sorted on i1 + -> Filter: (t2.i is not null) (cost=0.65 rows=4) + -> PQblock scan on t2 using i1 (cost=0.65 rows=4) -> Single-row index lookup on t1 using PRIMARY (i=t2.i) (cost=1.10 rows=1) DROP TABLE t1; diff --git a/mysql-test/r/loose_scan.result-pq b/mysql-test/r/loose_scan.result-pq index 31ac0b5dbe2f..954da2b1c4b9 100644 --- a/mysql-test/r/loose_scan.result-pq +++ b/mysql-test/r/loose_scan.result-pq @@ -141,7 +141,7 @@ SELECT t2.col_varchar_key FROM t2 WHERE t2.pk > t1.col_int id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL # 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL # 100.00 NULL -2 SIMPLE t2 NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL # 100.00 Using where; Using index +2 SIMPLE t2 NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL # 100.00 Using where; Using index; LooseScan 2 SIMPLE t3 NULL ref col_varchar_key col_varchar_key 7 test.t2.col_varchar_key # 100.00 Using index Warnings: Note 1276 Field or reference 'test.t1.col_int' of SELECT #2 was resolved in SELECT #1 @@ -189,15 +189,15 @@ FROM t3 JOIN t4 ON t3.pk = t4.pk ); EXPLAIN -> Parallel scan on - -> Inner hash join (t2.b = t1.a) (cost=2.90 rows=2) + -> Inner hash join (t2.b = t1.a) (cost=2.00 rows=2) -> Table scan on t2 (cost=0.18 rows=3) -> Hash - -> Nested loop semijoin (cost=2.05 rows=2) - -> Nested loop inner join (cost=1.15 rows=2) - -> PQblock scan on t1 (cost=0.45 rows=2) + -> Nested loop inner join (cost=1.15 rows=2) + -> PQblock scan on t1 (cost=0.45 rows=2) + -> Nested loop semijoin with duplicate removal on b_key (cost=1.00 rows=1) -> Index lookup on t3 using b_key (b=t1.a) (cost=0.30 rows=1) - -> Filter: (t4.pk = t3.pk) (cost=0.30 rows=1) - -> Table scan on t4 (cost=0.30 rows=2) + -> Filter: (t4.pk = t3.pk) (cost=0.30 rows=1) + -> Table scan on t4 (cost=0.30 rows=2) SELECT * FROM t1 diff --git a/mysql-test/r/opt_hints_join_order.result-pq b/mysql-test/r/opt_hints_join_order.result-pq index 536ffba15891..6364553df5c0 100644 --- a/mysql-test/r/opt_hints_join_order.result-pq +++ b/mysql-test/r/opt_hints_join_order.result-pq @@ -26,11 +26,12 @@ count(*) explain SELECT count(*) FROM t1 JOIN t2 JOIN t3 WHERE t1.f1 IN (SELECT f1 FROM t4) AND t2.f1 IN (SELECT f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) explain SELECT /*+ QB_NAME(q1) JOIN_PREFIX(t3, t2, t2@subq2) */ count(*) FROM t1 JOIN t2 JOIN t3 @@ -79,11 +80,12 @@ explain SELECT /*+ JOIN_SUFFIX(t3, t2) JOIN_SUFFIX(t2, t1) */ count(*) FROM t1 J WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) Warnings: Warning 3126 Hint JOIN_SUFFIX( `t2`,`t1`) is ignored as conflicting/duplicated Note 1003 /* select#1 */ select /*+ JOIN_SUFFIX(@`select#1` `t3`,`t2`) */ count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) @@ -97,11 +99,12 @@ explain SELECT /*+ JOIN_ORDER(t3, t2) JOIN_ORDER(t1, t2, t5) */ count(*) FROM t1 WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Start temporary -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 100.00 Using join buffer (hash join) -1 SIMPLE t5 NULL eq_ref PRIMARY PRIMARY 4 test.t2.f1 1 100.00 Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Start temporary +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 100.00 Using join buffer (hash join) +2 SIMPLE t5 NULL eq_ref PRIMARY PRIMARY 4 test.t2.f1 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select /*+ JOIN_ORDER(@`select#1` `t3`,`t2`) JOIN_ORDER(@`select#1` `t1`,`t2`,`t5`) */ count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t5`.`f1` = `test`.`t2`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) # Unresoled table name t7 in JOIN_ORDER hint, hint ignored @@ -116,11 +119,12 @@ explain SELECT /*+ JOIN_ORDER(t1, t7, t5) */ count(*) FROM t1 JOIN t2 JOIN t3 WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) Warnings: Warning 3128 Unresolved name `t7` for JOIN_ORDER hint Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) @@ -154,11 +158,12 @@ explain SELECT /*+ JOIN_ORDER(t3, t2) JOIN_ORDER(t2, t3) */ count(*) FROM t1 JOI WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ JOIN_ORDER(@`select#1` `t3`,`t2`) */ count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) # JOIN_SUFFIX is silently ignored @@ -171,11 +176,12 @@ explain SELECT /*+ JOIN_ORDER(t3, t2) JOIN_SUFFIX(t3) */ count(*) FROM t1 JOIN t WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ JOIN_ORDER(@`select#1` `t3`,`t2`) */ count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) # JOIN_PREFIX is silently ignored @@ -188,11 +194,12 @@ explain SELECT /*+ JOIN_ORDER(t3, t2) JOIN_PREFIX(t2) */ count(*) FROM t1 JOIN t WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ JOIN_ORDER(@`select#1` `t3`,`t2`) */ count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) # All hints are applicable @@ -337,11 +344,12 @@ explain SELECT /*+ QB_NAME(q1) */ count(*) FROM t1 JOIN t2 JOIN t3 WHERE t1.f1 IN (SELECT /*+ QB_NAME(subq1) */ f1 FROM t4) AND t2.f1 IN (SELECT /*+ QB_NAME(subq2) */ f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ QB_NAME(`q1`) */ count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) SELECT count(*) FROM t1 JOIN t2 STRAIGHT_JOIN t3 @@ -351,11 +359,12 @@ count(*) explain SELECT count(*) FROM t1 JOIN t2 STRAIGHT_JOIN t3 WHERE t1.f1 IN (SELECT f1 FROM t4) AND t2.f1 IN (SELECT f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` straight_join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) # t3 can not be first @@ -366,11 +375,12 @@ count(*) explain SELECT /*+ JOIN_PREFIX(t3, t1) */ count(*) FROM t1 JOIN t2 STRAIGHT_JOIN t3 WHERE t1.f1 IN (SELECT f1 FROM t4) AND t2.f1 IN (SELECT f1 FROM t5); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) -1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) -1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t5 NULL index PRIMARY PRIMARY 4 NULL 1 100.00 Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 2 100.00 Using join buffer (hash join) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 33.33 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 5 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select count(0) AS `count(*)` from `test`.`t5` join `test`.`t1` join `test`.`t2` straight_join `test`.`t3` semi join (`test`.`t4`) where ((`test`.`t2`.`f1` = `test`.`t5`.`f1`) and (`test`.`t1`.`f1` = `test`.`t4`.`f1`)) # hint is applicable @@ -993,8 +1003,9 @@ FROM ( SELECT * FROM t1 ) AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias1.f2 = alias2.f3 WHERE alias2.f2 IS NULL HAVING (field1 != 3 AND field1 >= 8); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL ref f2 f2 5 const 1 100.00 Using index condition; Using where -1 SIMPLE t1 NULL ref f2 f2 5 test.t2.f3 1 100.00 Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL ref f2 f2 5 const 1 100.00 Using index condition; Using where +2 SIMPLE t1 NULL ref f2 f2 5 test.t2.f3 1 100.00 Using index Warnings: Warning 3128 Unresolved name `alias1` for JOIN_PREFIX hint Note 1003 /* select#1 */ select `test`.`t2`.`f3` AS `field1` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`f2` = `test`.`t2`.`f3`) and (`test`.`t2`.`f2` is null)) having ((`field1` <> 3) and (`field1` >= 8)) @@ -1116,11 +1127,12 @@ COUNT(*) FROM t1 JOIN t2 AS ta3 JOIN t2 AS ta4 WHERE ta4.f1 IN (SELECT /*+ QB_NAME(qb1) */ f1 FROM t4) AND ta3.f2 IN (SELECT /*+ QB_NAME(qb2) */ f2 FROM t2); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Using join buffer (hash join) -1 SIMPLE ta4 NULL eq_ref PRIMARY PRIMARY 4 test.t4.f1 1 100.00 Using index; End temporary -1 SIMPLE t2 NULL index f2 f2 5 NULL 3 66.67 Using where; Using index; LooseScan -1 SIMPLE ta3 NULL ref f2 f2 5 test.t2.f2 1 100.00 Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Using join buffer (hash join) +2 SIMPLE ta4 NULL eq_ref PRIMARY PRIMARY 4 test.t4.f1 1 100.00 Using index; End temporary +2 SIMPLE t2 NULL index f2 f2 5 NULL 3 66.67 Using where; Using index; LooseScan +2 SIMPLE ta3 NULL ref f2 f2 5 test.t2.f2 1 100.00 Using index Warnings: Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` join `test`.`t2` `ta3` join `test`.`t2` `ta4` semi join (`test`.`t4`) semi join (`test`.`t2`) where ((`test`.`ta3`.`f2` = `test`.`t2`.`f2`) and (`test`.`ta4`.`f1` = `test`.`t4`.`f1`)) SELECT /*+ JOIN_PREFIX(t2@qb2, t4@qb1, ta3, ta4) */ @@ -1134,11 +1146,12 @@ COUNT(*) FROM t1 JOIN t2 AS ta3 JOIN t2 AS ta4 WHERE ta4.f1 IN (SELECT /*+ QB_NAME(qb1) */ f1 FROM t4) AND ta3.f2 IN (SELECT /*+ QB_NAME(qb2) */ f2 FROM t2); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t2 NULL index f2 f2 5 NULL 3 100.00 Using where; Using index; Start temporary -1 SIMPLE t4 NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Using join buffer (hash join) -1 SIMPLE ta3 NULL ref f2 f2 5 test.t2.f2 1 100.00 Using index -1 SIMPLE ta4 NULL eq_ref PRIMARY PRIMARY 4 test.t4.f1 1 100.00 Using index; End temporary -1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 Using join buffer (hash join) +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t2 NULL index f2 f2 5 NULL 3 100.00 Using where; Using index; Start temporary +2 SIMPLE t4 NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Using join buffer (hash join) +2 SIMPLE ta3 NULL ref f2 f2 5 test.t2.f2 1 100.00 Using index +2 SIMPLE ta4 NULL eq_ref PRIMARY PRIMARY 4 test.t4.f1 1 100.00 Using index; End temporary +2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select /*+ JOIN_PREFIX(@`select#1` `t2`@`qb2`,`t4`@`qb1`,`ta3`,`ta4`) */ count(0) AS `COUNT(*)` from `test`.`t1` join `test`.`t2` `ta3` join `test`.`t2` `ta4` semi join (`test`.`t4`) semi join (`test`.`t2`) where ((`test`.`ta3`.`f2` = `test`.`t2`.`f2`) and (`test`.`ta4`.`f1` = `test`.`t4`.`f1`)) DROP TABLE t1, t2, t4; diff --git a/mysql-test/r/opt_hints_subquery.result-pq b/mysql-test/r/opt_hints_subquery.result-pq new file mode 100644 index 000000000000..5245e7f5fa70 --- /dev/null +++ b/mysql-test/r/opt_hints_subquery.result-pq @@ -0,0 +1,1928 @@ +# WL#8244 Hints for subquery execution +CREATE TABLE t1 (a INTEGER NOT NULL, b INT, PRIMARY KEY (a)); +CREATE TABLE t2 (a INTEGER NOT NULL, KEY (a)); +CREATE TABLE t3 (a INTEGER NOT NULL, b INT, KEY (a)); +INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40); +INSERT INTO t2 VALUES (2), (3), (4), (5); +INSERT INTO t3 VALUES (10,3), (20,4), (30,5); +ANALYZE TABLE t1, t2, t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK +This query will normally use Table Pull-out +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +Check that we can disable SEMIJOIN transformation +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Same with hint in outer query +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Query with two sub-queries +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT a FROM t1 tx) +AND t3.b IN (SELECT a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SIMPLE tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +2 SIMPLE ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`tx`.`a` = `test`.`t3`.`a`)) +No SEMIJOIN transformation for first subquery +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 tx) +AND t3.b IN (SELECT a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY)))) +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(`subq1`) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY)))) +No SEMIJOIN transformation for latter subquery +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT a FROM t1 tx) +AND t3.b IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +1 PRIMARY tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#3`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t1 on PRIMARY)))) +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@`subq2`) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +1 PRIMARY tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t1 on PRIMARY)))) +No SEMIJOIN transformation for any subquery +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) NO_SEMIJOIN(@`select#3`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where ((`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY))) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t1 on PRIMARY)))) +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) NO_SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) NO_SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where ((`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY))) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t1 on PRIMARY)))) +Query with nested sub-queries +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +2 SIMPLE tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE ty NULL eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t1` `ty` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`ty`.`a` = `test`.`tx`.`b`)) +No SEMIJOIN transformation for outer subquery +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY tx NULL eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where +2 DEPENDENT SUBQUERY ty NULL eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq1`) */ 1 from `test`.`t1` `ty` join `test`.`t1` `tx` where ((`test`.`ty`.`a` = `test`.`tx`.`b`) and ((`test`.`t3`.`a`) = `test`.`tx`.`a`)))) +No SEMIJOIN transformation for inner-most subquery +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +1 PRIMARY tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`tx`.`b`,(((`test`.`tx`.`b`) in t1 on PRIMARY)))) +No SEMIJOIN transformation at all +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) NO_SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) NO_SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY where (`test`.`tx`.`b`,(((`test`.`tx`.`b`) in t1 on PRIMARY)))))) +This query does not support SEMIJOIN. SEMIJOIN hint is ignored +EXPLAIN +SELECT /*+ SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`min(a)`))))) +This query will get LooseScan by default +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Let's turn off LooseScan, FirstMatch is then SELECTed +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +Let's also turn off FirstMatch, MatLookup is then used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE NULL eq_ref 4 test.t2.a 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (``.`a` = `test`.`t2`.`a`) +Let's also turn off Materialization, DuplicateWeedout should then be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, MATERIALIZATION) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +If we turn off all strategies, DuplicateWeedout should still be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, MATERIALIZATION, +DUPSWEEDOUT) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Turn off non-used strategies, nothing should change. Still Loosescan +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Test same query with SEMIJOIN hint +Forcing LooseScan, should not change anything +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Force FirstMatch +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +Force Materialization +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE NULL eq_ref 4 test.t2.a 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (``.`a` = `test`.`t2`.`a`) +Force DuplicateWeedout +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +If LooseScan is among candidates, it will be used +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, MATERIALIZATION, +DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Drop LooseScan from list of strategies, FirstMatch will be used +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +Drop FirstMatch, MatLookup is next +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE NULL eq_ref 4 test.t2.a 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (``.`a` = `test`.`t2`.`a`) +For this query LooseScan and Materialization is not applicable +EXPLAIN +SELECT * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 SIMPLE t3 NULL ref a a 4 test.t1.b 1 33.33 Using where; FirstMatch(t1) +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t3`.`b` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) +Turn off all applicable strategies. DuplicateWeedout should be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 SIMPLE NULL eq_ref 9 test.t1.b,test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`b` = `test`.`t1`.`a`) and (``.`a` = `test`.`t1`.`b`)) +Similar with SEMIJOIN hint +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 SIMPLE NULL eq_ref 9 test.t1.b,test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`b` = `test`.`t1`.`a`) and (``.`a` = `test`.`t1`.`b`)) +Test multiple subqueries. +Default for this query is Loosecan for first and FirstMatch for latter +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Forcing the default strategy should not change anything +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Forcing a strategy for one, may change the other due to cost changes +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Forcing same strategy for both +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t3) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Loosescan for both is not possible, ends up with DuplicateWeedout +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Swap strategies compared to default +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Different subsets of strategies for different subqueries +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) +SEMIJOIN(@subq2 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) SEMIJOIN(@`subq2` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Vice versa +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) +SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION, DUPSWEEDOUT) SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +Another combination +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, FIRSTMATCH) +SEMIJOIN(@subq2 LOOSESCAN, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION) SEMIJOIN(@`subq2` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Turn off default +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) +NO_SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Also turn off 2nd choice. Gives DuplicateWeedout over both +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH) +NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Also turn off DuplicateWeedout. Materialization is only one left. +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, DUPSWEEDOUT) +NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +Force materialization with SEMIJOIN hints instead +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) +SEMIJOIN(@subq2 MATERIALIZATION) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +This query gives DuplicateWeedout over both since combining +DuplicateWeedout with another strategy does not seem possible. +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) +SEMIJOIN(@subq2 DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +More alternatives for 2nd subquery gives Materialization for first +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) +SEMIJOIN(@subq2 LOOSESCAN, FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +A query with nested subqueries which by default will use FirstMatch +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Let's turn off FirstMatch, Materialization is then selected +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 MATERIALIZED t2 NULL ref a a 4 test.t3.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = ``.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Let's also turn off Materialization, DuplicateWeedout is then used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 NULL +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Also turn off DuplicateWeedout. LooseScan not usable; so still DuplicateWeedout +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 NULL +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +If we turn off all strategies, DuplicateWeedout should still be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, MATERIALIZATION, +DUPSWEEDOUT) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 NULL +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Test same query with SEMIJOIN hint +Force FirstMatch, should not change anything +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Force LooseScan, will use DuplicateWeedout +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 NULL +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Force Materialization +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 MATERIALIZED t2 NULL ref a a 4 test.t3.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = ``.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Force DuplicateWeedout +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 NULL +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +If FirstMatch is among candidates, it will be used +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, LOOSESCAN, +DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Drop FirstMatch. Materialization will be used +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, LOOSESCAN, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 MATERIALIZED t2 NULL ref a a 4 test.t3.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = ``.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Drop Materialization, DuplicateWeedout next +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 NULL +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Strategy hints on inner-most query is ignored since sj-nests are merged +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Ditto +EXPLAIN +SELECT /*+ SEMIJOIN(@subq2 MATERIALIZATION) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2` MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`b`)) +Turn off semijoin for outer subquery. FirstMatch is used for inner +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t3 NULL ref a a 4 func 1 100.00 Using where +2 DEPENDENT SUBQUERY t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; FirstMatch(t3) +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq1`) */ 1 from `test`.`t3` semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t3`.`b`) and ((`test`.`t1`.`a`) = `test`.`t3`.`a`)))) +Do not use FirstMatch for inner +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) NO_SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SUBQUERY NULL eq_ref 4 test.t3.b 1 100.00 NULL +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2` FIRSTMATCH) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (``.`a` = `test`.`t3`.`b`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +Do not use FirstMatch nor Materialization for inner +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) +NO_SEMIJOIN(@subq2 FIRSTMATCH, MATERIALIZATION) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SUBQUERY t2 NULL ref a a 4 test.t3.b 1 100.00 Using index; Start temporary; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2` FIRSTMATCH, MATERIALIZATION) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (`test`.`t2`.`a` = `test`.`t3`.`b`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +LooseScan is last resort +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) +NO_SEMIJOIN(@subq2 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (`test`.`t3`.`b` = `test`.`t2`.`a`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +Allow all stragies except default +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) +SEMIJOIN(@subq2 MATERIALIZATION, DUPSWEEDOUT, LOOSESCAN) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SUBQUERY NULL eq_ref 4 test.t3.b 1 100.00 NULL +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (``.`a` = `test`.`t3`.`b`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +Force a particular strategy +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2` LOOSESCAN) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (`test`.`t3`.`b` = `test`.`t2`.`a`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +Turn off semijoin for inner-most subquery. FirstMatch is used for outer +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 NULL +1 PRIMARY t3 NULL ref a a 4 test.t1.a 1 100.00 Using where; FirstMatch(t1) +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))) +Do not use FirstMatch for outer +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY NULL eq_ref 4 test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))) +Do not use FirstMatch nor Materialization for outer +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION) +NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +1 PRIMARY t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 End temporary +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))) +LooseScan can not be used since index scan would not be "covering" +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) +NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +1 PRIMARY t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 End temporary +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))) +Allow all stragies except default +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT, LOOSESCAN) +NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 PRIMARY NULL eq_ref 4 test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))) +Force a particular strategy +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 DUPSWEEDOUT) NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +1 PRIMARY t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 End temporary +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))) +Turn off semijoin for both subqueries +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) NO_SEMIJOIN(@subq2) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 +WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 DEPENDENT SUBQUERY t3 NULL index_subquery a a 4 func 1 100.00 Using where +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,(((`test`.`t1`.`a`) in t3 on a where (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t2 on a)))))) +Test hints with prepared statements +PREPARE stmt1 FROM "EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) + NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) + AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)"; +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +1 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +1 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +DEALLOCATE PREPARE stmt1; +Another Prepared Statement test +PREPARE stmt1 FROM "EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 + WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2))"; +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2` LOOSESCAN) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (`test`.`t3`.`b` = `test`.`t2`.`a`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +2 SUBQUERY t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SUBQUERY t3 NULL ALL a NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2` LOOSESCAN) NO_SEMIJOIN(@`subq1`) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` semi join (`test`.`t2`) where (`test`.`t3`.`b` = `test`.`t2`.`a`) ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) +DEALLOCATE PREPARE stmt1; +SET optimizer_switch = default; +Tests with non-default optimizer_switch settings +SET optimizer_switch = 'semijoin=off'; +No table pull-out for this query +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +This should not change anything +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Force semijoin +EXPLAIN +SELECT /*+ SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +Setting strategy should still force semijoin +Strategy is ignored since table pull-out is done +EXPLAIN +SELECT /*+ SEMIJOIN(@subq FIRSTMATCH) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq` FIRSTMATCH) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +Query with two sub-queries +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT a FROM t1 tx) +AND t3.b IN (SELECT a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where ((`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY))) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t1 on PRIMARY)))) +SEMIJOIN transformation for first subquery +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +1 PRIMARY tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`t3`.`b`,(((`test`.`t3`.`b`) in t1 on PRIMARY)))) +SEMIJOIN transformation for latter subquery +EXPLAIN +SELECT /*+ SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +1 PRIMARY ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY)))) +SEMIJOIN transformation for both subqueries +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1) SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SIMPLE tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +2 SIMPLE ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1`) SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`tx`.`a` = `test`.`t3`.`a`)) +Query with nested sub-queries +EXPLAIN +SELECT * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY where (`test`.`tx`.`b`,(((`test`.`tx`.`b`) in t1 on PRIMARY)))))) +SEMIJOIN transformation for outer subquery +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +1 PRIMARY tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`tx`.`b`,(((`test`.`tx`.`b`) in t1 on PRIMARY)))) +SEMIJOIN transformation for inner-most subquery +EXPLAIN +SELECT /*+ SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY tx NULL eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where +2 DEPENDENT SUBQUERY ty NULL eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq1`) */ 1 from `test`.`t1` `ty` join `test`.`t1` `tx` where ((`test`.`ty`.`a` = `test`.`tx`.`b`) and ((`test`.`t3`.`a`) = `test`.`tx`.`a`)))) +SEMIJOIN transformation for both +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1) SEMIJOIN(@subq2) */ * FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +2 SIMPLE tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE ty NULL eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2`) SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t1` `ty` join `test`.`t3` where ((`test`.`tx`.`a` = `test`.`t3`.`a`) and (`test`.`ty`.`a` = `test`.`tx`.`b`)) +Test strategies when some are disabled by optimizer_switch +SET optimizer_switch='semijoin=on'; +SET optimizer_switch='loosescan=off'; +This query will get LooseScan by default. FirstMatch now. +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +Let's turn off LooseScan also by hint, FirstMatch should still be SELECTed +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +Let's also turn off FirstMatch, MatLookup should then be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE NULL eq_ref 4 test.t2.a 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (``.`a` = `test`.`t2`.`a`) +Let's also turn off Materialization, DuplicateWeedout should then be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Let's force LooseScan back on +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Forcing another strategy +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using where; Using index +1 SIMPLE NULL eq_ref 4 test.t2.a 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (``.`a` = `test`.`t2`.`a`) +If LooseScan is among candidates, it is used even if originally disabled +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, MATERIALIZATION, +DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Disable another strategy +SET optimizer_switch='firstmatch=off'; +Turn on FirstMatch, but not LooseScan on with hint +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +Drop all remaining strategies with hint, should use DuplicateWeedout +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +For this query LooseScan and Materialization is not applicable +Should use DuplicateWeedout since FirstMatch is disabled +EXPLAIN +SELECT * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t3`.`b`) and (`test`.`t1`.`b` = `test`.`t3`.`a`)) +Turn off all applicable strategies. DuplicateWeedout should still be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 SIMPLE NULL eq_ref 9 test.t1.b,test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`b` = `test`.`t1`.`a`) and (``.`a` = `test`.`t1`.`b`)) +Reverse which strategies are allowed with hint +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 SIMPLE t3 NULL ref a a 4 test.t1.b 1 33.33 Using where; FirstMatch(t1) +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t3`.`b` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) +Default for this query is Loosecan for first and FirstMatch for latter +Since both strategies are disabled, will now use DuplicateWeedout +EXPLAIN +SELECT * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Allowing LooseScan and FirstMatch and optimizer_switch is ignored +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH) +SEMIJOIN(@subq2 LOOSESCAN, FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Forcing a disabled strategy for one +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; Start temporary +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; End temporary; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Forcing same strategy for both +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t3) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Swap strategies compared to default +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Different subsets of strategies for different subqueries +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) +SEMIJOIN(@subq2 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) SEMIJOIN(@`subq2` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +Turn off DuplicateWeedout for both. Materialization is left +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 DUPSWEEDOUT) +NO_SEMIJOIN(@subq2 DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` DUPSWEEDOUT) NO_SEMIJOIN(@`subq2` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +Forcing materialization should have same effect +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) +SEMIJOIN(@subq2 MATERIALIZATION) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +Turn off DuplicateWeedout for first. Materialization is used for both +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +Turn off DuplicateWeedout for second. Same effect. +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq2 DUPSWEEDOUT) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +1 SIMPLE NULL eq_ref 4 test.t1.a 1 100.00 NULL +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = ``.`a`) and (``.`a` = `test`.`t1`.`a`)) +Enable all strategies except DuplicateWeedout +SET optimizer_switch='firstmatch=on,loosescan=on,materialization=on,duplicateweedout=off'; +If we turn off all other strategies, DuplicateWeedout will be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, MATERIALIZATION) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +LooseScan and Materialization is not applicable, FirstMatch is used +EXPLAIN +SELECT * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 SIMPLE t3 NULL ref a a 4 test.t1.b 1 33.33 Using where; FirstMatch(t1) +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t3`.`b` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) +Turn off all applicable strategies. DuplicateWeedout should be used +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 SIMPLE NULL eq_ref 9 test.t1.b,test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`b` = `test`.`t1`.`a`) and (``.`a` = `test`.`t1`.`b`)) +Similar with SEMIJOIN hint +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 SIMPLE NULL eq_ref 9 test.t1.b,test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`b` = `test`.`t1`.`a`) and (``.`a` = `test`.`t1`.`b`)) +Disable all strategies +SET optimizer_switch='firstmatch=off,loosescan=off,materialization=off,duplicateweedout=off'; +DuplicateWeedout is then used +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Turning off extra strategies should not change anything +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Start temporary; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +2 SIMPLE t2 NULL ref a a 4 test.t3.a 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t2`.`a` = `test`.`t3`.`a`) +Turning on some strategies should give one of those +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION) */ * +FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t3 NULL ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2) +Warnings: +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where (`test`.`t3`.`a` = `test`.`t2`.`a`) +For this query that cannot use LooseScan or Materialization, +turning those on will still give DupliateWeedout +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +1 SIMPLE NULL eq_ref 9 test.t1.b,test.t1.a 1 100.00 NULL +2 MATERIALIZED t3 NULL ALL a NULL NULL NULL 3 100.00 NULL +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((``.`b` = `test`.`t1`.`a`) and (``.`a` = `test`.`t1`.`b`)) +Turning on FirstMatch should give FirstMatch +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH) */ * FROM t1 +WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +2 SIMPLE t3 NULL ref a a 4 test.t1.b 1 33.33 Using where; FirstMatch(t1) +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where ((`test`.`t3`.`b` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) +SET optimizer_switch = default; +Test that setting optimizer_switch after prepare will change strategy +PREPARE stmt1 FROM "EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) + NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) + AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)"; +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +1 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +SET optimizer_switch = 'duplicateweedout=off'; +Will now use materialization +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL NULL 100.00 NULL +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 .a 1 100.00 Using where +1 SIMPLE NULL eq_ref 4 test.t1.b 1 100.00 NULL +2 MATERIALIZED t3 NULL index a a 4 NULL 3 100.00 Using index +3 MATERIALIZED t2 NULL index a a 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((``.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = ``.`a`)) +SET optimizer_switch = 'duplicateweedout=on'; +Turn DuplicateWeedout back on +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; Start temporary +1 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +1 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; End temporary +Warnings: +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +DEALLOCATE PREPARE stmt1; +SET optimizer_switch = default; +Specifying two SEMIJOIN/NO_SEMIJOIN for same query block gives warning +First has effect, second is ignored +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SEMIJOIN( ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Try opposite order +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ SEMIJOIN() NO_SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Warning 3126 Hint NO_SEMIJOIN( ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +Specify at different levels, hint inside block has effect +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Warning 3126 Hint NO_SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +Specify at different levels, opposite order +EXPLAIN +SELECT /*+ SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) NO_SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Duplicate hints also gives warning, but hint has effect +EXPLAIN +SELECT /*+ SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Warning 3126 Hint SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) NO_SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint NO_SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Multiple subqueries with conflicting hints +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) NO_SEMIJOIN() */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) SEMIJOIN(LOOSESCAN) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SUBQUERY t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Warning 3126 Hint SEMIJOIN(@`subq1` LOOSESCAN) is ignored as conflicting/duplicated +Warning 3126 Hint SEMIJOIN(@`subq2` FIRSTMATCH) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` where true ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`)))))) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) NO_SEMIJOIN(LOOSESCAN) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) SEMIJOIN(LOOSESCAN) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Warning 3126 Hint SEMIJOIN(@`subq1` LOOSESCAN) is ignored as conflicting/duplicated +Warning 3126 Hint SEMIJOIN(@`subq2` FIRSTMATCH) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Conflicting hints in same hint comment +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Warning 3126 Hint SEMIJOIN(@`subq1` FIRSTMATCH) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) NO_SEMIJOIN(@subq1 LOOSESCAN) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Warning 3126 Hint NO_SEMIJOIN(@`subq1` LOOSESCAN) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +EXPLAIN +SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index; LooseScan +2 SIMPLE t1 NULL ALL PRIMARY NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +2 SIMPLE t3 NULL ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1) +Warnings: +Warning 3126 Hint NO_SEMIJOIN(@`subq1` FIRSTMATCH) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`)) +Non-supported strategies should give warnings +EXPLAIN +SELECT /*+ SEMIJOIN(@subq1 INTOEXISTS) NO_SEMIJOIN(@subq2 INTOEXISTS) */ * +FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) +AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE t3 NULL index a a 4 NULL 3 100.00 Using index; LooseScan +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where +2 SIMPLE t2 NULL ref a a 4 test.t1.b 1 100.00 Using index; FirstMatch(t1) +Warnings: +Warning 1064 Optimizer hint syntax error near 'INTOEXISTS) NO_SEMIJOIN(@subq2 INTOEXISTS) */ * +FROM t1 +WHERE t1.a IN (SELECT /*' at line 2 +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t3`.`a`)) +SUBQUERY tests +SUBQUERY should disable SEMIJOIN and use specified subquery strategy +EXPLAIN +SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +EXPLAIN +SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq`) */ `test`.`t1`.`a` from `test`.`t1` where true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`a`))))) +Query with two subqueries +EXPLAIN +SELECT /*+ SUBQUERY(@subq1 INTOEXISTS) SUBQUERY(@subq2 MATERIALIZATION) */ * +FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +3 SUBQUERY ty NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq1` INTOEXISTS) SUBQUERY(@`subq2` MATERIALIZATION) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where ((`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY))) and (`test`.`t3`.`b`,`test`.`t3`.`b` in ( (/* select#3 */ select /*+ QB_NAME(`subq2`) */ `test`.`ty`.`a` from `test`.`t1` `ty` where true ), (`test`.`t3`.`b` in on where ((`test`.`t3`.`b` = ``.`a`)))))) +Query with nested sub-queries +EXPLAIN +SELECT /*+ SUBQUERY(@subq1 INTOEXISTS) SUBQUERY(@subq2 MATERIALIZATION) */ * +FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +2 DEPENDENT SUBQUERY tx NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where +3 SUBQUERY ty NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq2` MATERIALIZATION) SUBQUERY(@`subq1` INTOEXISTS) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a`,(((`test`.`t3`.`a`) in t1 on PRIMARY where (`test`.`tx`.`b`,`test`.`tx`.`b` in ( (/* select#3 */ select /*+ QB_NAME(`subq2`) */ `test`.`ty`.`a` from `test`.`t1` `ty` where true ), (`test`.`tx`.`b` in on where ((`test`.`tx`.`b` = ``.`a`)))))))) +EXPLAIN +SELECT /*+ SUBQUERY(@subq1 MATERIALIZATION) SUBQUERY(@subq2 INTOEXISTS) */ * +FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx +WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty)); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where +2 SUBQUERY tx NULL ALL PRIMARY NULL NULL NULL 4 100.00 Using where +3 DEPENDENT SUBQUERY ty NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq2` INTOEXISTS) SUBQUERY(@`subq1` MATERIALIZATION) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where (`test`.`t3`.`a`,`test`.`t3`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`tx`.`a` from `test`.`t1` `tx` where (`test`.`tx`.`b`,(((`test`.`tx`.`b`) in t1 on PRIMARY))) ), (`test`.`t3`.`a` in on where ((`test`.`t3`.`a` = ``.`a`))))) +This query does not support SEMIJOIN. Materialization is default +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`min(a)`))))) +Use In-to-exists instead +EXPLAIN +SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq`) */ 1 from `test`.`t1` group by `test`.`t1`.`a` having ((`test`.`t2`.`a`) = (min(`test`.`t1`.`a`))))) +For this query In-to-exists is default +EXPLAIN +SELECT a, a IN (SELECT a FROM t1) FROM t2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,(`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) AS `a IN (SELECT a FROM t1)` from `test`.`t2` +Force Subquery Materialization +EXPLAIN +SELECT a, a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) */ a FROM t1) FROM t2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` MATERIALIZATION) */ `test`.`t2`.`a` AS `a`,(`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`a`))))) AS `a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) */ a FROM t1)` from `test`.`t2` +EXPLAIN +SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ a, +a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1) FROM t2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a`,(`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq`) */ `test`.`t1`.`a` from `test`.`t1` where true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`a`))))) AS `a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1)` from `test`.`t2` +This query does not support Subquery Materialization due to type mismatch +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ concat(sum(b),"") FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 NULL +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq`) */ 1 from `test`.`t1` group by `test`.`t1`.`a` having ((`test`.`t2`.`a`) = (concat(sum(`test`.`t1`.`b`),''))))) +Trying to force Subquery Materialization will not change anything +EXPLAIN +SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ concat(sum(b),"") FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 NULL +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq`) */ 1 from `test`.`t1` group by `test`.`t1`.`a` having ((`test`.`t2`.`a`) = (concat(sum(`test`.`t1`.`b`),''))))) +Test hints with prepared statements +PREPARE stmt1 FROM "EXPLAIN +SELECT /*+ SUBQUERY(@subq1 MATERIALIZATION) + SUBQUERY(@subq2 INTOEXISTS) */ * FROM t1 +WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3) + AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)"; +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +2 SUBQUERY t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq1` MATERIALIZATION) SUBQUERY(@`subq2` INTOEXISTS) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` where true ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) and (`test`.`t1`.`b`,(((`test`.`t1`.`b`) in t2 on a)))) +EXECUTE stmt1; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 4 100.00 Using where +3 DEPENDENT SUBQUERY t2 NULL index_subquery a a 4 func 1 100.00 Using index +2 SUBQUERY t3 NULL index a a 4 NULL 3 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq1` MATERIALIZATION) SUBQUERY(@`subq2` INTOEXISTS) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a`,`test`.`t1`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`t3`.`a` from `test`.`t3` where true ), (`test`.`t1`.`a` in on where ((`test`.`t1`.`a` = ``.`a`))))) and (`test`.`t1`.`b`,(((`test`.`t1`.`b`) in t2 on a)))) +DEALLOCATE PREPARE stmt1; +Test optimizer_switch settings with SUBQUERY hint +SET optimizer_switch='materialization=off'; +This query will now use In-to-exist +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(/* select#2 */ select /*+ QB_NAME(`subq`) */ 1 from `test`.`t1` group by `test`.`t1`.`a` having ((`test`.`t2`.`a`) = (min(`test`.`t1`.`a`))))) +Force it to use Materialization +EXPLAIN +SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`min(a)`))))) +SET optimizer_switch='materialization=on,subquery_materialization_cost_based=off'; +This query will now use materialization +EXPLAIN +SELECT a, a IN (SELECT a FROM t1) FROM t2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,(`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`a`))))) AS `a IN (SELECT a FROM t1)` from `test`.`t2` +Force In-to-exists +EXPLAIN +SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ a, +a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1) FROM t2; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a`,(`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) AS `a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1)` from `test`.`t2` +Specifying both strategies should give a warning +EXPLAIN +SELECT /*+ SUBQUERY(@subq1 MATERIALIZATION, INTOEXISTS) +SUBQUERY(@subq2 MATERIALIZATION, INTOEXISTS) */ * +FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SIMPLE tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +2 SIMPLE ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +Warnings: +Warning 1064 Optimizer hint syntax error near ', INTOEXISTS) +SUBQUERY(@subq2 MATERIALIZATION, INTOEXISTS) */ * +FROM t3 +WHERE t3' at line 2 +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`tx`.`a` = `test`.`t3`.`a`)) +Non-supported strategies should give warnings +EXPLAIN +SELECT /*+ SUBQUERY(@subq1 FIRSTMATCH) SUBQUERY(@subq2 LOOSESCAN) */ * +FROM t3 +WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx) +AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL a NULL NULL NULL 3 100.00 Using where +2 SIMPLE tx NULL eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index +2 SIMPLE ty NULL eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index +Warnings: +Warning 1064 Optimizer hint syntax error near 'FIRSTMATCH) SUBQUERY(@subq2 LOOSESCAN) */ * +FROM t3 +WHERE t3.a IN (SELECT /*+ QB' at line 2 +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t1` `ty` join `test`.`t3` where ((`test`.`ty`.`a` = `test`.`t3`.`b`) and (`test`.`tx`.`a` = `test`.`t3`.`a`)) +SET optimizer_switch= default; +Specifying two SUBQUERY for same query block gives warning +First has effect, second is ignored +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) SUBQUERY(INTOEXISTS) */ a +FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY( INTOEXISTS) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` where true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`a`))))) +Try opposite order +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) SUBQUERY(MATERIALIZATION) */ a +FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY( MATERIALIZATION) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Specify at different levels, hint inside block has effect +EXPLAIN +SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SUBQUERY(INTOEXISTS) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY(@`subq` MATERIALIZATION) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Specify at different levels, opposite order +EXPLAIN +SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SUBQUERY(MATERIALIZATION) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 SUBQUERY t1 NULL index PRIMARY PRIMARY 4 NULL 4 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY(@`subq` INTOEXISTS) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,`test`.`t2`.`a` in ( (/* select#2 */ select /*+ QB_NAME(`subq`) */ `test`.`t1`.`a` from `test`.`t1` where true ), (`test`.`t2`.`a` in on where ((`test`.`t2`.`a` = ``.`a`))))) +Specifying combinations of SUBQUERY and SEMIJOIN/NO_SEMIJOIN +for same query block gives warning +First has effect, second is ignored +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SEMIJOIN( ) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Try opposite order +EXPLAIN +SELECT * FROM t2 +WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() SUBQUERY(MATERIALIZATION) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY( MATERIALIZATION) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +Specify at different levels, hint inside block has effect +EXPLAIN +SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 4 100.00 Parallel execute (1 workers) +2 SIMPLE t2 NULL index a a 4 NULL 4 100.00 Using index +2 SIMPLE t1 NULL eq_ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY(@`subq` MATERIALIZATION) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`) +EXPLAIN +SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) NO_SEMIJOIN() */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SUBQUERY(@`subq` INTOEXISTS) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +EXPLAIN +SELECT /*+ SEMIJOIN(@subq FIRSTMATCH) */ * FROM t2 +WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SUBQUERY(@subq INTOEXISTS) */ a FROM t1); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t2 NULL index NULL a 4 NULL 4 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t1 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index +Warnings: +Warning 3126 Hint SEMIJOIN(@`subq` FIRSTMATCH) is ignored as conflicting/duplicated +Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a`,(((`test`.`t2`.`a`) in t1 on PRIMARY))) +drop table t1, t2, t3; diff --git a/mysql-test/r/subquery_exists.result-pq b/mysql-test/r/subquery_exists.result-pq index fe13731b1977..d48972f21c56 100644 --- a/mysql-test/r/subquery_exists.result-pq +++ b/mysql-test/r/subquery_exists.result-pq @@ -269,8 +269,8 @@ pk uk ukn ik d EXPLAIN SELECT * FROM t2 AS ot WHERE EXISTS (SELECT * FROM t1 AS it WHERE it.ik = ot.pk); id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 Parallel execute (1 workers) -2 SIMPLE it NULL index ik ik 5 NULL 3 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 3 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE it NULL index ik ik 5 NULL 3 100.00 Using where; Using index; LooseScan 2 SIMPLE ot NULL eq_ref PRIMARY PRIMARY 4 test.it.ik 1 100.00 Using index Warnings: Note 1276 Field or reference 'test.ot.pk' of SELECT #2 was resolved in SELECT #1 diff --git a/mysql-test/r/subquery_sj_all.result-pq b/mysql-test/r/subquery_sj_all.result-pq index 7282ea35fdf4..eeecb8a05f90 100644 --- a/mysql-test/r/subquery_sj_all.result-pq +++ b/mysql-test/r/subquery_sj_all.result-pq @@ -12170,8 +12170,8 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12253,7 +12253,7 @@ WHERE t3.pk < 3 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index +2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_all_bka.result-pq b/mysql-test/r/subquery_sj_all_bka.result-pq index 1d3b716adec2..e93b9fc0660f 100644 --- a/mysql-test/r/subquery_sj_all_bka.result-pq +++ b/mysql-test/r/subquery_sj_all_bka.result-pq @@ -12176,8 +12176,8 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12259,7 +12259,7 @@ WHERE t3.pk < 3 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index +2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_all_bka_nobnl.result-pq b/mysql-test/r/subquery_sj_all_bka_nobnl.result-pq index 03a84c52ddf0..897d426ee705 100644 --- a/mysql-test/r/subquery_sj_all_bka_nobnl.result-pq +++ b/mysql-test/r/subquery_sj_all_bka_nobnl.result-pq @@ -12180,8 +12180,8 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12263,7 +12263,7 @@ WHERE t3.pk < 3 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index +2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_loosescan.result-pq b/mysql-test/r/subquery_sj_loosescan.result-pq index ad15d7331ef1..5d4f8bb2170f 100644 --- a/mysql-test/r/subquery_sj_loosescan.result-pq +++ b/mysql-test/r/subquery_sj_loosescan.result-pq @@ -8775,8 +8775,8 @@ WHERE innr.col_varchar_key = 'a' OR innr.pk = 8) AND outr.col_varchar_nokey < 't' ORDER BY outr.col_varchar_key, outr.pk; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 20 55.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 55.00 Using where; Using index; Using temporary; Using filesort +1 SIMPLE NULL ALL NULL NULL NULL NULL 20 55.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 55.00 Using where; Using index; Using temporary; Using filesort; LooseScan 2 SIMPLE outr NULL ref col_varchar_key col_varchar_key 6 test.innr.col_varchar_key 1 33.33 Using where Warnings: Note 1003 /* select#1 */ select `test`.`outr`.`col_varchar_key` AS `x`,`test`.`outr`.`pk` AS `y` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_key` = `test`.`innr`.`col_varchar_key`) and (`test`.`outr`.`col_varchar_nokey` < 't') and ((`test`.`innr`.`col_varchar_key` = 'a') or (`test`.`innr`.`pk` = 8))) order by `test`.`outr`.`col_varchar_key`,`test`.`outr`.`pk` @@ -9866,7 +9866,7 @@ FROM t2 AS it1 JOIN t1 AS it2 ON it2.col_int_key = it1.pk); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 20 100.00 Parallel execute (1 workers) 2 SIMPLE ot1 NULL index col_varchar_key col_varchar_key 10 NULL 20 100.00 Using index -2 SIMPLE it1 NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 80.00 Using index +2 SIMPLE it1 NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 80.00 Using index; LooseScan 2 SIMPLE it2 NULL ref col_int_key col_int_key 4 test.it1.pk 1 10.00 Using where; FirstMatch(it1) 2 SIMPLE ot2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) Warnings: @@ -12088,8 +12088,8 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12171,7 +12171,7 @@ WHERE t3.pk < 3 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index +2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_loosescan_bka.result-pq b/mysql-test/r/subquery_sj_loosescan_bka.result-pq index 4725efb5adb0..f08accee4000 100644 --- a/mysql-test/r/subquery_sj_loosescan_bka.result-pq +++ b/mysql-test/r/subquery_sj_loosescan_bka.result-pq @@ -8776,8 +8776,8 @@ WHERE innr.col_varchar_key = 'a' OR innr.pk = 8) AND outr.col_varchar_nokey < 't' ORDER BY outr.col_varchar_key, outr.pk; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 20 55.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 55.00 Using where; Using index; Using temporary; Using filesort +1 SIMPLE NULL ALL NULL NULL NULL NULL 20 55.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 55.00 Using where; Using index; Using temporary; Using filesort; LooseScan 2 SIMPLE outr NULL ref col_varchar_key col_varchar_key 6 test.innr.col_varchar_key 1 33.33 Using where Warnings: Note 1003 /* select#1 */ select `test`.`outr`.`col_varchar_key` AS `x`,`test`.`outr`.`pk` AS `y` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_key` = `test`.`innr`.`col_varchar_key`) and (`test`.`outr`.`col_varchar_nokey` < 't') and ((`test`.`innr`.`col_varchar_key` = 'a') or (`test`.`innr`.`pk` = 8))) order by `test`.`outr`.`col_varchar_key`,`test`.`outr`.`pk` @@ -9867,7 +9867,7 @@ FROM t2 AS it1 JOIN t1 AS it2 ON it2.col_int_key = it1.pk); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 20 100.00 Parallel execute (1 workers) 2 SIMPLE ot1 NULL index col_varchar_key col_varchar_key 10 NULL 20 100.00 Using index -2 SIMPLE it1 NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 80.00 Using index +2 SIMPLE it1 NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 80.00 Using index; LooseScan 2 SIMPLE it2 NULL ref col_int_key col_int_key 4 test.it1.pk 1 10.00 Using where; FirstMatch(it1) 2 SIMPLE ot2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where; Using join buffer (hash join) Warnings: @@ -12089,8 +12089,8 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where; Using join buffer (hash join) Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12172,7 +12172,7 @@ WHERE t3.pk < 3 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index +2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result-pq b/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result-pq index 30b1602de29b..1138187d5d42 100644 --- a/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result-pq +++ b/mysql-test/r/subquery_sj_loosescan_bka_nobnl.result-pq @@ -8778,8 +8778,8 @@ WHERE innr.col_varchar_key = 'a' OR innr.pk = 8) AND outr.col_varchar_nokey < 't' ORDER BY outr.col_varchar_key, outr.pk; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 20 55.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 55.00 Using where; Using index; Using temporary; Using filesort +1 SIMPLE NULL ALL NULL NULL NULL NULL 20 55.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 55.00 Using where; Using index; Using temporary; Using filesort; LooseScan 2 SIMPLE outr NULL ref col_varchar_key col_varchar_key 6 test.innr.col_varchar_key 1 33.33 Using where Warnings: Note 1003 /* select#1 */ select `test`.`outr`.`col_varchar_key` AS `x`,`test`.`outr`.`pk` AS `y` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_key` = `test`.`innr`.`col_varchar_key`) and (`test`.`outr`.`col_varchar_nokey` < 't') and ((`test`.`innr`.`col_varchar_key` = 'a') or (`test`.`innr`.`pk` = 8))) order by `test`.`outr`.`col_varchar_key`,`test`.`outr`.`pk` @@ -9869,7 +9869,7 @@ FROM t2 AS it1 JOIN t1 AS it2 ON it2.col_int_key = it1.pk); id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 20 100.00 Parallel execute (1 workers) 2 SIMPLE ot1 NULL index col_varchar_key col_varchar_key 10 NULL 20 100.00 Using index -2 SIMPLE it1 NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 80.00 Using index +2 SIMPLE it1 NULL index PRIMARY,col_varchar_key col_varchar_key 10 NULL 20 80.00 Using index; LooseScan 2 SIMPLE it2 NULL ref col_int_key col_int_key 4 test.it1.pk 1 10.00 Using where; FirstMatch(it1) 2 SIMPLE ot2 NULL ALL NULL NULL NULL NULL 20 10.00 Using where Warnings: @@ -12083,8 +12083,8 @@ WHERE innr.pk <= 7 ) ; id select_type table partitions type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 Parallel execute (1 workers) -2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index +1 SIMPLE NULL ALL NULL NULL NULL NULL 2 100.00 LooseScan; Parallel execute (1 workers) +2 SIMPLE innr NULL index PRIMARY,col_varchar_key col_varchar_key 7 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE outr NULL ALL NULL NULL NULL NULL 3 33.33 Using where Warnings: Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t1` `outr` semi join (`test`.`t2` `innr`) where ((`test`.`outr`.`col_varchar_nokey` = `test`.`innr`.`col_varchar_key`) and (`test`.`innr`.`pk` <= 7)) @@ -12166,7 +12166,7 @@ WHERE t3.pk < 3 id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) 2 SIMPLE t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL -2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index +2 SIMPLE t3 NULL index PRIMARY,c1_key c1_key 6 NULL 2 100.00 Using where; Using index; LooseScan 2 SIMPLE t2 NULL ref PRIMARY,c1_key c1_key 6 test.t3.c1 1 33.33 Using where; Using index Warnings: Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`i1` AS `i1`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`c1` AS `c1` from `test`.`t1` join `test`.`t2` semi join (`test`.`t3`) where ((`test`.`t2`.`c1` = `test`.`t3`.`c1`) and (`test`.`t3`.`pk` < 3) and (`test`.`t1`.`i1` >= `test`.`t2`.`pk`)) diff --git a/mysql-test/suite/opt_trace/r/subquery_no_prot.result-pq b/mysql-test/suite/opt_trace/r/subquery_no_prot.result-pq new file mode 100644 index 000000000000..d61b7687831a --- /dev/null +++ b/mysql-test/suite/opt_trace/r/subquery_no_prot.result-pq @@ -0,0 +1,3440 @@ +SET optimizer_trace_max_mem_size=1048576; +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); +# 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; +(SELECT a FROM t1 WHERE t1.a=t2.a) a +NULL 1 +2 2 + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +SELECT (SELECT a FROM t1 WHERE t1.a=t2.a), a FROM t2 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "expanded_query": "/* select#2 */ select `t1`.`a` from `t1` where (`t1`.`a` = `t2`.`a`)" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#1 */ select (/* select#2 */ select `t1`.`a` from `t1` where (`t1`.`a` = `t2`.`a`)) AS `(SELECT a FROM t1 WHERE t1.a=t2.a)`,`t2`.`a` AS `a` from `t2`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "table_dependencies": [ + { + "table": "`t2`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "rows_estimation": [ + { + "table": "`t2`", + "table_scan": { + "rows": 2, + "cost": 0.5011 + } /* table_scan */ + } + ] /* rows_estimation */ + }, + { + "considered_execution_plans": "..." + }, + { + "attaching_conditions_to_tables": { + "original_condition": null, + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "table": "`t2`", + "attached": null + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "finalizing_table_conditions": [ + ] /* finalizing_table_conditions */ + }, + { + "refine_plan": [ + { + "table": "`t2`" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_optimization": { + "select#": 2, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "(`t1`.`a` = `t2`.`a`)", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "(`t1`.`a` = `t2`.`a`)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "(`t1`.`a` = `t2`.`a`)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "(`t1`.`a` = `t2`.`a`)" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "substitute_generated_columns": { + } /* substitute_generated_columns */ + }, + { + "table_dependencies": [ + { + "table": "`t1`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "ref_optimizer_key_uses": [ + ] /* ref_optimizer_key_uses */ + }, + { + "rows_estimation": [ + { + "table": "`t1`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": false + } + ] /* rows_estimation */ + }, + { + "attaching_conditions_to_tables": { + "original_condition": "('2' = `t2`.`a`)", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "refine_plan": [ + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + }, + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + } + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +# 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; +(SELECT a FROM t1 WHERE t1.a=t2.a) a +NULL 1 +2 2 + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +SELECT (SELECT a FROM t1 WHERE t1.a=t2.a), a FROM t2 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "expanded_query": "/* select#2 */ select `t1`.`a` from `t1` where (`t1`.`a` = `t2`.`a`)" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#1 */ select (/* select#2 */ select `t1`.`a` from `t1` where (`t1`.`a` = `t2`.`a`)) AS `(SELECT a FROM t1 WHERE t1.a=t2.a)`,`t2`.`a` AS `a` from `t2`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "table_dependencies": [ + { + "table": "`t2`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "rows_estimation": [ + { + "table": "`t2`", + "table_scan": { + "rows": 2, + "cost": 0.5011 + } /* table_scan */ + } + ] /* rows_estimation */ + }, + { + "considered_execution_plans": "..." + }, + { + "attaching_conditions_to_tables": { + "original_condition": null, + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "table": "`t2`", + "attached": null + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "finalizing_table_conditions": [ + ] /* finalizing_table_conditions */ + }, + { + "refine_plan": [ + { + "table": "`t2`" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_optimization": { + "select#": 2, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "(`t1`.`a` = `t2`.`a`)", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "(`t1`.`a` = `t2`.`a`)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "(`t1`.`a` = `t2`.`a`)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "(`t1`.`a` = `t2`.`a`)" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "substitute_generated_columns": { + } /* substitute_generated_columns */ + }, + { + "table_dependencies": [ + { + "table": "`t1`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "ref_optimizer_key_uses": [ + ] /* ref_optimizer_key_uses */ + }, + { + "rows_estimation": [ + { + "table": "`t1`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": false + } + ] /* rows_estimation */ + }, + { + "attaching_conditions_to_tables": { + "original_condition": "('2' = `t2`.`a`)", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "refine_plan": [ + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + } + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +DROP TABLE t1,t2; +SET @@optimizer_trace_features="default"; +CREATE TABLE t1 (a FLOAT(5,4) zerofill); +Warnings: +Warning 1681 The ZEROFILL attribute is deprecated and will be removed in a future release. Use the LPAD function to zero-pad numbers, or store the formatted numbers in a CHAR column. +Warning 1681 Specifying number of digits for floating point data types is deprecated and will be removed in a future release. +CREATE TABLE t2 (a FLOAT(5,4),b FLOAT(2,0)); +Warnings: +Warning 1681 Specifying number of digits for floating point data types is deprecated and will be removed in a future release. +Warning 1681 Specifying number of digits for floating point data types is deprecated and will be removed in a future release. +SELECT t1.a +FROM t1 +WHERE t1.a= (SELECT b FROM t2 LIMIT 1) AND NOT +t1.a= (SELECT a FROM t2 LIMIT 1) ; +a + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +SELECT t1.a +FROM t1 +WHERE t1.a= (SELECT b FROM t2 LIMIT 1) AND NOT +t1.a= (SELECT a FROM t2 LIMIT 1) { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "expanded_query": "/* select#2 */ select `t2`.`b` from `t2` limit 1" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_preparation": { + "select#": 3, + "steps": [ + { + "expanded_query": "/* select#3 */ select `t2`.`a` from `t2` limit 1" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#1 */ select `t1`.`a` AS `a` from `t1` where ((`t1`.`a` = (/* select#2 */ select `t2`.`b` from `t2` limit 1)) and (`t1`.`a` <> (/* select#3 */ select `t2`.`a` from `t2` limit 1)))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`t1`.`a` = (/* select#2 */ select `t2`.`b` from `t2` limit 1)) and (`t1`.`a` <> (/* select#3 */ select `t2`.`a` from `t2` limit 1)))", + "steps": [ + { + "transformation": "equality_propagation", + "subselect_evaluation": [ + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_optimization": { + "select#": 2, + "steps": [ + { + "table_dependencies": [ + { + "table": "`t2`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "rows_estimation": [ + { + "table": "`t2`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": true + } + ] /* rows_estimation */ + } + ] /* steps */, + "empty_result": { + "cause": "no matching row in const table" + } /* empty_result */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + } + ] /* subselect_evaluation */, + "resulting_condition": "((NULL <> (/* select#3 */ select `t2`.`a` from `t2` limit 1)) and multiple equal((/* select#2 */ select NULL from `t2` limit 1), `t1`.`a`))" + }, + { + "transformation": "constant_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "((NULL <> (/* select#3 */ select `t2`.`a` from `t2` limit 1)) and multiple equal((/* select#2 */ select NULL from `t2` limit 1), `t1`.`a`))" + }, + { + "transformation": "trivial_condition_removal", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": null + } + ] /* steps */ + } /* condition_processing */ + } + ] /* steps */, + "empty_result": { + "cause": "Impossible WHERE" + } /* empty_result */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +SELECT 1 FROM DUAL +WHERE NOT EXISTS +(SELECT * FROM t2 WHERE a = 50 AND b = 3); +1 +1 + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +SELECT 1 FROM DUAL +WHERE NOT EXISTS +(SELECT * FROM t2 WHERE a = 50 AND b = 3) { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "expanded_query": "/* select#2 */ select 1 from `t2` where ((`t2`.`a` = 50) and (`t2`.`b` = 3))" + }, + { + "transformation": { + "select#": 2, + "from": "EXISTS (SELECT)", + "to": "semijoin", + "chosen": false + } /* transformation */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#1 */ select 1 AS `1` from DUAL where exists(/* select#2 */ select 1 from `t2` where ((`t2`.`a` = 50) and (`t2`.`b` = 3))) is false" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "exists(/* select#2 */ select 1 from `t2` where ((`t2`.`a` = 50) and (`t2`.`b` = 3))) is false", + "steps": [ + { + "transformation": "equality_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "exists(/* select#2 */ select 1 from `t2` where ((`t2`.`a` = 50) and (`t2`.`b` = 3))) is false" + }, + { + "transformation": "constant_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "exists(/* select#2 */ select 1 from `t2` where ((`t2`.`a` = 50) and (`t2`.`b` = 3))) is false" + }, + { + "transformation": "trivial_condition_removal", + "subselect_evaluation": [ + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_optimization": { + "select#": 2, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`t2`.`a` = 50) and (`t2`.`b` = 3))", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "((`t2`.`a` = 50) and (`t2`.`b` = 3))" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "((`t2`.`a` = 50) and (`t2`.`b` = 3))" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": null + } + ] /* steps */ + } /* condition_processing */ + } + ] /* steps */, + "empty_result": { + "cause": "Impossible WHERE" + } /* empty_result */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + } + ] /* subselect_evaluation */, + "resulting_condition": null + } + ] /* steps */ + } /* condition_processing */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +SELECT 1 FROM DUAL WHERE NOT EXISTS (SELECT DISTINCT(a) FROM t2 GROUP BY a ORDER BY b); +1 +1 + +SELECT * FROM information_schema.OPTIMIZER_TRACE; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +SELECT 1 FROM DUAL WHERE NOT EXISTS (SELECT DISTINCT(a) FROM t2 GROUP BY a ORDER BY b) { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "transformations_to_subquery": [ + "removed_ordering", + "removed_distinct", + "removed_grouping" + ] /* transformations_to_subquery */ + }, + { + "expanded_query": "/* select#2 */ select `t2`.`a` from `t2`" + }, + { + "transformation": { + "select#": 2, + "from": "EXISTS (SELECT)", + "to": "semijoin", + "chosen": false + } /* transformation */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#1 */ select 1 AS `1` from DUAL where exists(/* select#2 */ select `t2`.`a` from `t2`) is false" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "exists(/* select#2 */ select `t2`.`a` from `t2`) is false", + "steps": [ + { + "transformation": "equality_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "exists(/* select#2 */ select `t2`.`a` from `t2`) is false" + }, + { + "transformation": "constant_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "exists(/* select#2 */ select `t2`.`a` from `t2`) is false" + }, + { + "transformation": "trivial_condition_removal", + "subselect_evaluation": [ + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_optimization": { + "select#": 2, + "steps": [ + { + "table_dependencies": [ + { + "table": "`t2`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "rows_estimation": [ + { + "table": "`t2`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": true + } + ] /* rows_estimation */ + } + ] /* steps */, + "empty_result": { + "cause": "no matching row in const table" + } /* empty_result */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + } + ] /* subselect_evaluation */, + "resulting_condition": null + } + ] /* steps */ + } /* condition_processing */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 + +DROP TABLE t1,t2; +# +# BUG#12905521 - ASSERT IN OPT_TRACE_STMT::SYNTAX_ERROR ON SELECT +# DISTINCT/MIN/JOIN/SUBQ QUERY +# +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'); +Warnings: +Warning 1364 Field 'pk' doesn't have a default value +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; +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; +field1 field2 field3 field4 field5 field6 +select * from information_schema.optimizer_trace; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +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 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 5, + "steps": [ + { + "expanded_query": "/* select#5 */ select `sq3_alias2`.`pk` AS `pk`,`sq3_alias2`.`col_int_nokey` AS `col_int_nokey`,`sq3_alias2`.`col_int_key` AS `col_int_key`,`sq3_alias2`.`col_date_key` AS `col_date_key`,`sq3_alias2`.`col_date_nokey` AS `col_date_nokey`,`sq3_alias2`.`col_time_key` AS `col_time_key`,`sq3_alias2`.`col_time_nokey` AS `col_time_nokey`,`sq3_alias2`.`col_datetime_key` AS `col_datetime_key`,`sq3_alias2`.`col_datetime_nokey` AS `col_datetime_nokey`,`sq3_alias2`.`col_varchar_key` AS `col_varchar_key`,`sq3_alias2`.`col_varchar_nokey` AS `col_varchar_nokey` from (`t5` `sq3_alias1` join `t4` `sq3_alias2`)" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "derived": { + "table": "``.`` `alias2`", + "select#": 5, + "merged": true + } /* derived */ + }, + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "join_preparation": { + "select#": 3, + "steps": [ + { + "transformations_to_subquery": [ + "removed_distinct" + ] /* transformations_to_subquery */ + }, + { + "expanded_query": "/* select#3 */ select `c_sq1_alias2`.`col_int_nokey` AS `c_sq1_field1` from (`t4` `c_sq1_alias2` left join `t3` `c_sq1_alias1` on((`c_sq1_alias2`.`col_int_nokey` = `c_sq1_alias1`.`pk`))) where (`c_sq1_alias2`.`col_varchar_key` = `sq1_alias2`.`col_varchar_nokey`)" + }, + { + "transformation": { + "select#": 3, + "from": "EXISTS (SELECT)", + "to": "semijoin", + "chosen": false + } /* transformation */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#2 */ select min(`sq1_alias1`.`col_varchar_nokey`) AS `sq1_field1` from (`t1` `sq1_alias1` join (`t5` `sq1_alias2` left join `t5` `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#3 */ select `c_sq1_alias2`.`col_int_nokey` AS `c_sq1_field1` from (`t4` `c_sq1_alias2` left join `t3` `c_sq1_alias1` on((`c_sq1_alias2`.`col_int_nokey` = `c_sq1_alias1`.`pk`))) where (`c_sq1_alias2`.`col_varchar_key` = `sq1_alias2`.`col_varchar_nokey`))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_preparation": { + "select#": 4, + "steps": [ + { + "expanded_query": "/* select#4 */ select max(`sq2_alias1`.`pk`) AS `sq2_field1` from `t5` `sq2_alias1`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_preparation": { + "select#": 6, + "steps": [ + { + "expanded_query": "/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from (`t3` `sq4_alias1` join (`t3` `sq4_alias3` left join `t2` `sq4_alias2` 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`))" + }, + { + "transformation": { + "select#": 6, + "from": "IN (SELECT)", + "to": "semijoin", + "chosen": false + } /* transformation */ + }, + { + "transformation": { + "select#": 6, + "from": "IN (SELECT)", + "to": "EXISTS (CORRELATED SELECT)", + "chosen": true, + "evaluating_constant_where_conditions": [ + ] /* evaluating_constant_where_conditions */ + } /* transformation */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "expanded_query": "/* select#1 */ select `alias1`.`col_varchar_key` AS `field1`,`alias1`.`col_date_key` AS `field2`,(/* select#2 */ select min(`sq1_alias1`.`col_varchar_nokey`) AS `sq1_field1` from (`t1` `sq1_alias1` join (`t5` `sq1_alias2` left join `t5` `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#3 */ select `c_sq1_alias2`.`col_int_nokey` AS `c_sq1_field1` from (`t4` `c_sq1_alias2` left join `t3` `c_sq1_alias1` 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#4 */ select max(`sq2_alias1`.`pk`) AS `sq2_field1` from `t5` `sq2_alias1`) AS `field4`,`sq3_alias2`.`col_varchar_nokey` AS `field5`,`sq3_alias2`.`col_varchar_nokey` AS `field6` from ((`t4` `alias3` left join ((`t5` `sq3_alias1` join `t4` `sq3_alias2`)) on((`alias3`.`col_varchar_key` = `sq3_alias2`.`col_varchar_key`))) left join `t5` `alias1` on((`alias3`.`col_int_key` = `sq3_alias2`.`pk`))) where ((`alias1`.`col_varchar_nokey`,(/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from (`t3` `sq4_alias1` join (`t3` `sq4_alias3` left join `t2` `sq4_alias2` 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_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`)))) and (`alias1`.`col_int_key` <> 214)) group by `field1`,`field2`,`field3`,`field4`,`field5`,`field6`" + }, + { + "transformations_to_nested_joins": { + "transformations": [ + "outer_join_to_inner_join", + "JOIN_condition_to_WHERE", + "parenthesis_removal" + ] /* transformations */, + "expanded_query": "/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from `t3` `sq4_alias1` join `t3` `sq4_alias3` join `t2` `sq4_alias2` where ((`sq4_alias2`.`col_int_key` < `alias1`.`col_int_nokey`) and (`sq4_alias3`.`col_varchar_nokey` <> `alias1`.`col_varchar_key`) and ((`alias1`.`col_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`) and (`sq4_alias3`.`col_varchar_nokey` = `sq4_alias2`.`col_varchar_key`) and (`sq4_alias3`.`pk` = `sq4_alias2`.`col_int_key`))" + } /* transformations_to_nested_joins */ + }, + { + "transformations_to_nested_joins": { + "transformations": [ + "parenthesis_removal" + ] /* transformations */, + "expanded_query": "/* select#3 */ select `c_sq1_alias2`.`col_int_nokey` AS `c_sq1_field1` from `t4` `c_sq1_alias2` left join `t3` `c_sq1_alias1` on((`c_sq1_alias2`.`col_int_nokey` = `c_sq1_alias1`.`pk`)) where (`c_sq1_alias2`.`col_varchar_key` = `sq1_alias2`.`col_varchar_nokey`)" + } /* transformations_to_nested_joins */ + }, + { + "transformations_to_nested_joins": { + "transformations": [ + "outer_join_to_inner_join", + "JOIN_condition_to_WHERE", + "parenthesis_removal" + ] /* transformations */, + "expanded_query": "/* select#2 */ select min(`sq1_alias1`.`col_varchar_nokey`) AS `sq1_field1` from `t1` `sq1_alias1` join `t5` `sq1_alias2` join `t5` `sq1_alias3` where (exists(/* select#3 */ select `c_sq1_alias2`.`col_int_nokey` AS `c_sq1_field1` from `t4` `c_sq1_alias2` left join `t3` `c_sq1_alias1` on((`c_sq1_alias2`.`col_int_nokey` = `c_sq1_alias1`.`pk`)) where (`c_sq1_alias2`.`col_varchar_key` = `sq1_alias2`.`col_varchar_nokey`)) and (`sq1_alias3`.`col_varchar_nokey` = `sq1_alias2`.`col_varchar_key`) and (`sq1_alias3`.`col_varchar_nokey` = `sq1_alias2`.`col_varchar_key`))" + } /* transformations_to_nested_joins */ + }, + { + "transformations_to_nested_joins": { + "transformations": [ + "outer_join_to_inner_join", + "JOIN_condition_to_WHERE", + "parenthesis_removal" + ] /* transformations */, + "expanded_query": "/* select#1 */ select `alias1`.`col_varchar_key` AS `field1`,`alias1`.`col_date_key` AS `field2`,(/* select#2 */ select min(`sq1_alias1`.`col_varchar_nokey`) AS `sq1_field1` from `t1` `sq1_alias1` join `t5` `sq1_alias2` join `t5` `sq1_alias3` where (exists(/* select#3 */ select `c_sq1_alias2`.`col_int_nokey` AS `c_sq1_field1` from `t4` `c_sq1_alias2` left join `t3` `c_sq1_alias1` on((`c_sq1_alias2`.`col_int_nokey` = `c_sq1_alias1`.`pk`)) where (`c_sq1_alias2`.`col_varchar_key` = `sq1_alias2`.`col_varchar_nokey`)) and (`sq1_alias3`.`col_varchar_nokey` = `sq1_alias2`.`col_varchar_key`) and (`sq1_alias3`.`col_varchar_nokey` = `sq1_alias2`.`col_varchar_key`))) AS `field3`,(/* select#4 */ select max(`sq2_alias1`.`pk`) AS `sq2_field1` from `t5` `sq2_alias1`) AS `field4`,`sq3_alias2`.`col_varchar_nokey` AS `field5`,`sq3_alias2`.`col_varchar_nokey` AS `field6` from `t4` `alias3` join `t5` `sq3_alias1` join `t4` `sq3_alias2` join `t5` `alias1` where ((`alias1`.`col_varchar_nokey`,(/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from `t3` `sq4_alias1` join `t3` `sq4_alias3` join `t2` `sq4_alias2` where ((`sq4_alias2`.`col_int_key` < `alias1`.`col_int_nokey`) and (`sq4_alias3`.`col_varchar_nokey` <> `alias1`.`col_varchar_key`) and ((`alias1`.`col_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`) and (`sq4_alias3`.`col_varchar_nokey` = `sq4_alias2`.`col_varchar_key`) and (`sq4_alias3`.`pk` = `sq4_alias2`.`col_int_key`)))) and (`alias1`.`col_int_key` <> 214) and (`alias3`.`col_int_key` = `sq3_alias2`.`pk`) and (`alias3`.`col_varchar_key` = `sq3_alias2`.`col_varchar_key`)) group by `field1`,`field2`,`field3`,`field4`,`field5`,`field6`" + } /* transformations_to_nested_joins */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`alias1`.`col_varchar_nokey`,(/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from `t3` `sq4_alias1` join `t3` `sq4_alias3` join `t2` `sq4_alias2` where ((`sq4_alias2`.`col_int_key` < `alias1`.`col_int_nokey`) and (`sq4_alias3`.`col_varchar_nokey` <> `alias1`.`col_varchar_key`) and ((`alias1`.`col_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`) and (`sq4_alias3`.`col_varchar_nokey` = `sq4_alias2`.`col_varchar_key`) and (`sq4_alias3`.`pk` = `sq4_alias2`.`col_int_key`)))) and (`alias1`.`col_int_key` <> 214) and (`alias3`.`col_int_key` = `sq3_alias2`.`pk`) and (`alias3`.`col_varchar_key` = `sq3_alias2`.`col_varchar_key`))", + "steps": [ + { + "transformation": "equality_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "((`alias1`.`col_varchar_nokey`,(/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from `t3` `sq4_alias1` join `t3` `sq4_alias3` join `t2` `sq4_alias2` where ((`sq4_alias2`.`col_int_key` < `alias1`.`col_int_nokey`) and (`sq4_alias3`.`col_varchar_nokey` <> `alias1`.`col_varchar_key`) and ((`alias1`.`col_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`) and (`sq4_alias3`.`col_varchar_nokey` = `sq4_alias2`.`col_varchar_key`) and (`sq4_alias3`.`pk` = `sq4_alias2`.`col_int_key`)))) and (`alias1`.`col_int_key` <> 214) and multiple equal(`alias3`.`col_int_key`, `sq3_alias2`.`pk`) and multiple equal(`alias3`.`col_varchar_key`, `sq3_alias2`.`col_varchar_key`))" + }, + { + "transformation": "constant_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "((`alias1`.`col_varchar_nokey`,(/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from `t3` `sq4_alias1` join `t3` `sq4_alias3` join `t2` `sq4_alias2` where ((`sq4_alias2`.`col_int_key` < `alias1`.`col_int_nokey`) and (`sq4_alias3`.`col_varchar_nokey` <> `alias1`.`col_varchar_key`) and ((`alias1`.`col_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`) and (`sq4_alias3`.`col_varchar_nokey` = `sq4_alias2`.`col_varchar_key`) and (`sq4_alias3`.`pk` = `sq4_alias2`.`col_int_key`)))) and (`alias1`.`col_int_key` <> 214) and multiple equal(`alias3`.`col_int_key`, `sq3_alias2`.`pk`) and multiple equal(`alias3`.`col_varchar_key`, `sq3_alias2`.`col_varchar_key`))" + }, + { + "transformation": "trivial_condition_removal", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "((`alias1`.`col_varchar_nokey`,(/* select#6 */ select `sq4_alias1`.`col_varchar_key` AS `sq4_field1` from `t3` `sq4_alias1` join `t3` `sq4_alias3` join `t2` `sq4_alias2` where ((`sq4_alias2`.`col_int_key` < `alias1`.`col_int_nokey`) and (`sq4_alias3`.`col_varchar_nokey` <> `alias1`.`col_varchar_key`) and ((`alias1`.`col_varchar_nokey`) = `sq4_alias1`.`col_varchar_key`) and (`sq4_alias3`.`col_varchar_nokey` = `sq4_alias2`.`col_varchar_key`) and (`sq4_alias3`.`pk` = `sq4_alias2`.`col_int_key`)))) and (`alias1`.`col_int_key` <> 214) and multiple equal(`alias3`.`col_int_key`, `sq3_alias2`.`pk`) and multiple equal(`alias3`.`col_varchar_key`, `sq3_alias2`.`col_varchar_key`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "substitute_generated_columns": { + } /* substitute_generated_columns */ + }, + { + "table_dependencies": [ + { + "table": "`t5` `alias1`", + "row_may_be_null": true, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + }, + { + "table": "`t5` `sq3_alias1`", + "row_may_be_null": true, + "map_bit": 1, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + }, + { + "table": "`t4` `sq3_alias2`", + "row_may_be_null": true, + "map_bit": 2, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + }, + { + "table": "`t4` `alias3`", + "row_may_be_null": false, + "map_bit": 3, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "ref_optimizer_key_uses": [ + { + "table": "`t4` `sq3_alias2`", + "field": "pk", + "equals": "`alias3`.`col_int_key`", + "null_rejecting": true + }, + { + "table": "`t4` `sq3_alias2`", + "field": "col_varchar_key", + "equals": "`alias3`.`col_varchar_key`", + "null_rejecting": true + }, + { + "table": "`t4` `alias3`", + "field": "col_varchar_key", + "equals": "`sq3_alias2`.`col_varchar_key`", + "null_rejecting": true + }, + { + "table": "`t4` `alias3`", + "field": "col_int_key", + "equals": "`sq3_alias2`.`pk`", + "null_rejecting": true + } + ] /* ref_optimizer_key_uses */ + }, + { + "rows_estimation": [ + { + "table": "`t5` `alias1`", + "range_analysis": { + "table_scan": { + "rows": 3, + "cost": 2.9085 + } /* table_scan */, + "potential_range_indexes": [ + { + "index": "PRIMARY", + "usable": false, + "cause": "not_applicable" + }, + { + "index": "col_int_key", + "usable": true, + "key_parts": [ + "col_int_key" + ] /* key_parts */ + }, + { + "index": "col_varchar_key", + "usable": false, + "cause": "not_applicable" + } + ] /* potential_range_indexes */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "impossible_range": true + } /* range_analysis */, + "rows": 0, + "cause": "impossible_where_condition" + }, + { + "table": "`t5` `sq3_alias1`", + "table_scan": { + "rows": 3, + "cost": 0.5085 + } /* table_scan */ + }, + { + "table": "`t4` `sq3_alias2`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": false + }, + { + "table": "`t4` `alias3`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": false + } + ] /* rows_estimation */ + }, + { + "considered_execution_plans": [ + { + "plan_prefix": [ + "`t4` `sq3_alias2`", + "`t4` `alias3`", + "`t5` `alias1`" + ] /* plan_prefix */, + "table": "`t5` `sq3_alias1`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 3, + "access_type": "scan", + "resulting_rows": 3, + "cost": 0.8085, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 3, + "cost_for_plan": 0.8085, + "chosen": true + } + ] /* considered_execution_plans */ + } + ] /* steps */, + "empty_result": { + "cause": "no matching row in const table" + } /* empty_result */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 +set optimizer_switch=@old_opt_switch; +drop table t1,t2,t3,t4,t5; +# +# BUG#12905758 - ASSERT IN OPT_TRACE_STMT::SYNTAX_ERROR ON +# SELECT/SUBQ/SUM QUERY +# +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, CHARSET utf8mb4; +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; +field1 +select * from information_schema.optimizer_trace; +QUERY TRACE MISSING_BYTES_BEYOND_MAX_MEM_SIZE INSUFFICIENT_PRIVILEGES +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 { + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "expanded_query": "/* select#2 */ select sum(`subquery1_t1`.`col_int_nokey`) AS `subquery1_field1` from `t1` `subquery1_t1`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_preparation": { + "select#": 3, + "steps": [ + { + "expanded_query": "/* select#3 */ select 5 from `t2`" + }, + { + "transformation": { + "select#": 3, + "from": "IN (SELECT)", + "to": "EXISTS (CORRELATED SELECT)", + "chosen": true, + "evaluating_constant_where_conditions": [ + ] /* evaluating_constant_where_conditions */ + } /* transformation */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "IN_uses_bisection": true + }, + { + "expanded_query": "/* select#1 */ select (/* select#2 */ select sum(`subquery1_t1`.`col_int_nokey`) AS `subquery1_field1` from `t1` `subquery1_t1`) AS `field1` from (`t1` `table1` straight_join `t1` `table2` on((`table2`.`col_varchar_key` = `table1`.`col_varchar_key`))) where (((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18))) order by `field1` desc" + }, + { + "transformations_to_nested_joins": { + "transformations": [ + "JOIN_condition_to_WHERE", + "parenthesis_removal" + ] /* transformations */, + "expanded_query": "/* select#1 */ select (/* select#2 */ select sum(`subquery1_t1`.`col_int_nokey`) AS `subquery1_field1` from `t1` `subquery1_t1`) AS `field1` from `t1` `table1` straight_join `t1` `table2` where (((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18)) and (`table2`.`col_varchar_key` = `table1`.`col_varchar_key`)) order by `field1` desc" + } /* transformations_to_nested_joins */ + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "(((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18)) and (`table2`.`col_varchar_key` = `table1`.`col_varchar_key`))", + "steps": [ + { + "transformation": "equality_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "(((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18)) and multiple equal(`table2`.`col_varchar_key`, `table1`.`col_varchar_key`))" + }, + { + "transformation": "constant_propagation", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "(((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18)) and multiple equal(`table2`.`col_varchar_key`, `table1`.`col_varchar_key`))" + }, + { + "transformation": "trivial_condition_removal", + "subselect_evaluation": [ + ] /* subselect_evaluation */, + "resulting_condition": "(((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18)) and multiple equal(`table2`.`col_varchar_key`, `table1`.`col_varchar_key`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "substitute_generated_columns": { + } /* substitute_generated_columns */ + }, + { + "table_dependencies": [ + { + "table": "`t1` `table1`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + }, + { + "table": "`t1` `table2`", + "row_may_be_null": false, + "map_bit": 1, + "depends_on_map_bits": [ + 0 + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "ref_optimizer_key_uses": [ + { + "table": "`t1` `table1`", + "field": "col_varchar_key", + "equals": "`table2`.`col_varchar_key`", + "null_rejecting": true + }, + { + "table": "`t1` `table2`", + "field": "col_varchar_key", + "equals": "`table1`.`col_varchar_key`", + "null_rejecting": true + } + ] /* ref_optimizer_key_uses */ + }, + { + "rows_estimation": [ + { + "table": "`t1` `table1`", + "range_analysis": { + "table_scan": { + "rows": 2, + "cost": 2.8056 + } /* table_scan */, + "potential_range_indexes": [ + { + "index": "PRIMARY", + "usable": true, + "key_parts": [ + "pk" + ] /* key_parts */ + }, + { + "index": "col_varchar_key", + "usable": false, + "cause": "not_applicable" + } + ] /* potential_range_indexes */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "group_index_range": { + "chosen": false, + "cause": "not_single_table" + } /* group_index_range */, + "skip_scan_range": { + "chosen": false, + "cause": "not_single_table" + } /* skip_scan_range */, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "PRIMARY", + "ranges": [ + "18 <= pk <= 18", + "192 <= pk <= 192" + ] /* ranges */, + "index_dives_for_eq_ranges": true, + "rowid_ordered": false, + "using_mrr": false, + "index_only": false, + "rows": 2, + "cost": 1.21, + "chosen": true + } + ] /* range_scan_alternatives */, + "analyzing_roworder_intersect": { + "usable": false, + "cause": "too_few_roworder_scans" + } /* analyzing_roworder_intersect */ + } /* analyzing_range_alternatives */, + "chosen_range_access_summary": { + "range_access_plan": { + "type": "range_scan", + "index": "PRIMARY", + "rows": 2, + "ranges": [ + "18 <= pk <= 18", + "192 <= pk <= 192" + ] /* ranges */ + } /* range_access_plan */, + "rows_for_plan": 2, + "cost_for_plan": 1.21, + "chosen": true + } /* chosen_range_access_summary */ + } /* range_analysis */ + }, + { + "table": "`t1` `table2`", + "table_scan": { + "rows": 2, + "cost": 0.5056 + } /* table_scan */ + } + ] /* rows_estimation */ + }, + { + "considered_execution_plans": [ + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`t1` `table1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "col_varchar_key", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 2, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "range", + "range_details": { + "used_index": "PRIMARY" + } /* range_details */, + "resulting_rows": 2, + "cost": 1.41, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 2, + "cost_for_plan": 1.41, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t1` `table1`" + ] /* plan_prefix */, + "table": "`t1` `table2`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "col_varchar_key", + "rows": 2, + "cost": 1.4, + "chosen": true + }, + { + "rows_to_scan": 2, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 2, + "cost": 0.9057, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 4, + "cost_for_plan": 2.3157, + "chosen": true + } + ] /* rest_of_plan */ + } + ] /* considered_execution_plans */ + }, + { + "attaching_conditions_to_tables": { + "original_condition": "((`table2`.`col_varchar_key` = `table1`.`col_varchar_key`) and ((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))) and (`table1`.`pk` in (192,18)))", + "attached_conditions_computation": [ + { + "table": "`t1` `table2`", + "rechecking_index_usage": { + "recheck_reason": "not_first_table", + "range_analysis": { + "table_scan": { + "rows": 2, + "cost": 2.8056 + } /* table_scan */, + "potential_range_indexes": [ + { + "index": "PRIMARY", + "usable": false, + "cause": "not_applicable" + }, + { + "index": "col_varchar_key", + "usable": true, + "key_parts": [ + "col_varchar_key", + "col_int_key" + ] /* key_parts */ + } + ] /* potential_range_indexes */, + "setup_range_conditions": [ + ] /* setup_range_conditions */, + "group_index_range": { + "chosen": false, + "cause": "not_single_table" + } /* group_index_range */, + "skip_scan_range": { + "chosen": false, + "cause": "not_single_table" + } /* skip_scan_range */, + "analyzing_range_alternatives": { + "range_scan_alternatives": [ + { + "index": "col_varchar_key", + "chosen": false, + "cause": "depends_on_unread_values" + } + ] /* range_scan_alternatives */, + "analyzing_roworder_intersect": { + "usable": false, + "cause": "too_few_roworder_scans" + } /* analyzing_roworder_intersect */ + } /* analyzing_range_alternatives */ + } /* range_analysis */ + } /* rechecking_index_usage */ + } + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "table": "`t1` `table1`", + "attached": "(`table1`.`pk` in (192,18))" + }, + { + "table": "`t1` `table2`", + "attached": "((`table2`.`col_varchar_key` = `table1`.`col_varchar_key`) and ((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))))" + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "optimizing_distinct_group_by_order_by": { + "simplifying_order_by": { + "original_clause": "`field1` desc", + "items": [ + { + "item": "(/* select#2 */ select sum(`subquery1_t1`.`col_int_nokey`) AS `subquery1_field1` from `t1` `subquery1_t1`)", + "subselect_evaluation": [ + { + "subselect_execution": { + "select#": 2, + "steps": [ + { + "join_optimization": { + "select#": 2, + "steps": [ + { + "table_dependencies": [ + { + "table": "`t1` `subquery1_t1`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "rows_estimation": [ + { + "table": "`t1` `subquery1_t1`", + "table_scan": { + "rows": 2, + "cost": 0.5056 + } /* table_scan */ + } + ] /* rows_estimation */ + }, + { + "considered_execution_plans": [ + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`t1` `subquery1_t1`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 2, + "access_type": "scan", + "resulting_rows": 2, + "cost": 0.7056, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 2, + "cost_for_plan": 0.7056, + "chosen": true + } + ] /* considered_execution_plans */ + }, + { + "attaching_conditions_to_tables": { + "original_condition": null, + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "table": "`t1` `subquery1_t1`", + "attached": null + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "optimizing_distinct_group_by_order_by": { + } /* optimizing_distinct_group_by_order_by */ + }, + { + "finalizing_table_conditions": [ + ] /* finalizing_table_conditions */ + }, + { + "refine_plan": [ + { + "table": "`t1` `subquery1_t1`" + } + ] /* refine_plan */ + }, + { + "considering_tmp_tables": [ + ] /* considering_tmp_tables */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ + } /* subselect_execution */ + } + ] /* subselect_evaluation */, + "uses_only_constant_tables": true + } + ] /* items */, + "resulting_clause_is_simple": true, + "resulting_clause": "" + } /* simplifying_order_by */ + } /* optimizing_distinct_group_by_order_by */ + }, + { + "finalizing_table_conditions": [ + { + "table": "`t1` `table1`", + "original_table_condition": "(`table1`.`pk` in (192,18))", + "final_table_condition ": "(`table1`.`pk` in (192,18))" + }, + { + "table": "`t1` `table2`", + "original_table_condition": "((`table2`.`col_varchar_key` = `table1`.`col_varchar_key`) and ((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))))", + "final_table_condition ": "((`table2`.`col_varchar_key` = `table1`.`col_varchar_key`) and ((`table2`.`col_int_nokey`,(/* select#3 */ select 5 from `t2` where (outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)))))" + } + ] /* finalizing_table_conditions */ + }, + { + "refine_plan": [ + { + "table": "`t1` `table1`", + "pushed_index_condition": "(`table1`.`pk` in (192,18))", + "table_condition_attached": null + }, + { + "table": "`t1` `table2`" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_optimization": { + "select#": 3, + "steps": [ + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "(outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "(outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "(outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "(outer_field_is_not_null, ((`table2`.`col_int_nokey`) <> 5), true)" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "substitute_generated_columns": { + } /* substitute_generated_columns */ + }, + { + "table_dependencies": [ + { + "table": "`t2`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "ref_optimizer_key_uses": [ + ] /* ref_optimizer_key_uses */ + }, + { + "rows_estimation": [ + { + "table": "`t2`", + "rows": 1, + "cost": 1, + "table_type": "system", + "empty": true + } + ] /* rows_estimation */ + }, + { + "transformation": { + "select#": 3, + "from": "IN (SELECT)", + "to": "materialization", + "possible": false, + "cause": "not an IN predicate" + } /* transformation */ + }, + { + "transformation": { + "select#": 3, + "from": "IN (SELECT)", + "to": "EXISTS (CORRELATED SELECT)", + "put_1_in_SELECT_list": true + } /* transformation */ + } + ] /* steps */, + "empty_result": { + "cause": "no matching row in const table" + } /* empty_result */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} 0 0 +drop table t1,t2; + +# +# Tracing of semijoin loosescan +# +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)) charset utf8mb4; +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); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref a a 5 const 8 100.00 Using index; LooseScan +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 100 10.00 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = 3)) +# 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); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref a a 5 const 8 100.00 Using index; LooseScan +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = 3) and ((`test`.`t2`.`b` + 0) = 3) and ((`test`.`t2`.`a` + 0) = `test`.`t1`.`b`)) +# 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'; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL index a a 10 NULL 100 100.00 Using index; LooseScan +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 100 1.00 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`a`) and (`test`.`t2`.`filler` = 'abc') and (`test`.`t2`.`filler` = (`test`.`t1`.`a` * 3))) +SELECT show_json_object('"recalculate_access_paths_and_cost": {', TRACE) +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +show_json_object('"recalculate_access_paths_and_cost": {', TRACE) +"recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 12.996, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_1": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "covering_scan": { + "cost": 1.0484, + "chosen": true + } /* covering_scan */ + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + }, + { + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 0.1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 10, + "cost": 112.04, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */ + } + ] /* tables */ + } +# 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); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 100 100.00 Using where +1 SIMPLE t1 NULL ref a a 10 test.t2.b,test.t2.a 1 100.00 Using index; Start temporary; End temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`b`) and (`test`.`t2`.`filler` = (`test`.`t2`.`b` * 3))) +SELECT show_json_object('"searching_loose_scan_index": {', TRACE) +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +show_json_object('"searching_loose_scan_index": {', TRACE) +"searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "index_handles_needed_semijoin_equalities": false + } + ] /* indexes */ + } +# 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); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 NULL +1 SIMPLE t1 NULL index a a 10 NULL 100 100.00 Using where; Using index; LooseScan +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 100 1.00 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`filler` AS `filler`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` `t3` join `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`a`) and (`test`.`t2`.`filler` = `test`.`t3`.`filler`) and (`test`.`t3`.`filler` = (`test`.`t1`.`a` * 3))) +SELECT show_json_object('"recalculate_access_paths_and_cost": {', TRACE) +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +show_json_object('"recalculate_access_paths_and_cost": {', TRACE) +"recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 1299.6, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_1": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "covering_scan": { + "cost": 1.0484, + "chosen": true + } /* covering_scan */ + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + }, + { + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 16, + "resulting_rows": 100, + "cost": 100051, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */ + } + ] /* tables */ + } +# In plan t3-t1-t2, 3rd outer expression is dependent only on +# previous tables => 3rd sj equality is bound. +# 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); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 NULL ALL NULL NULL NULL NULL 100 100.00 NULL +1 SIMPLE t1 NULL index a a 10 NULL 100 100.00 Using where; Using index; LooseScan +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 100 1.00 Using where; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`filler` AS `filler`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`filler` AS `filler` from `test`.`t2` `t3` join `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`a`) and ((`test`.`t3`.`filler` + 2) = (`test`.`t1`.`a` * 3)) and ((`test`.`t2`.`filler` + 10) = (`test`.`t3`.`filler` + 20))) +SELECT show_json_object('"considered_execution_plans": [', TRACE) +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +show_json_object('"considered_execution_plans": [', TRACE) +"considered_execution_plans": [ + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`t2` `t3`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 12.996, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 100, + "cost_for_plan": 12.996, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t2` `t3`" + ] /* plan_prefix */, + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003.5, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 1016.5, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t2` `t3`", + "`t2`" + ] /* plan_prefix */, + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "rows": 1, + "cost": 3500, + "chosen": true + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 32, + "resulting_rows": 100, + "cost": 100097, + "chosen": false + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 4516.5, + "semijoin_strategy_choice": [ + { + "strategy": "DuplicatesWeedout", + "cost": 6517.5, + "rows": 10000, + "duplicate_tables_left": true, + "chosen": true + } + ] /* semijoin_strategy_choice */, + "chosen": true + } + ] /* rest_of_plan */ + }, + { + "plan_prefix": [ + "`t2` `t3`" + ] /* plan_prefix */, + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003.5, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 1016.5, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t2` `t3`", + "`t1`" + ] /* plan_prefix */, + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 16, + "resulting_rows": 100, + "cost": 100051, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 1, + "rows_for_plan": 10000, + "cost_for_plan": 101067, + "semijoin_strategy_choice": [ + { + "strategy": "LooseScan", + "recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 1299.6, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_1": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "covering_scan": { + "cost": 1.0484, + "chosen": true + } /* covering_scan */ + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + }, + { + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 16, + "resulting_rows": 100, + "cost": 100051, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */ + } + ] /* tables */ + } /* recalculate_access_paths_and_cost */, + "cost": 101065, + "rows": 100, + "chosen": true + }, + { + "strategy": "DuplicatesWeedout", + "cost": 102078, + "rows": 100, + "duplicate_tables_left": false, + "chosen": false + } + ] /* semijoin_strategy_choice */, + "chosen": true, + "cause": "previous_plan_used_disabled_strategy" + } + ] /* rest_of_plan */ + } + ] /* rest_of_plan */ + }, + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 12.996, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 100, + "cost_for_plan": 12.996, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t2`" + ] /* plan_prefix */, + "table": "`t2` `t3`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003.5, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 1016.5, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t2`", + "`t2` `t3`" + ] /* plan_prefix */, + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "rows": 1, + "cost": 3500, + "chosen": true + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 32, + "resulting_rows": 100, + "cost": 100097, + "chosen": false + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 4516.5, + "semijoin_strategy_choice": [ + { + "strategy": "DuplicatesWeedout", + "cost": 6517.5, + "rows": 10000, + "duplicate_tables_left": true, + "chosen": true + } + ] /* semijoin_strategy_choice */, + "chosen": false, + "cause": "plan_uses_disabled_strategy" + } + ] /* rest_of_plan */ + }, + { + "plan_prefix": [ + "`t2`" + ] /* plan_prefix */, + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "rows": 1, + "cost": 35, + "chosen": true + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003.5, + "chosen": false + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 100, + "cost_for_plan": 47.996, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t2`", + "`t1`" + ] /* plan_prefix */, + "table": "`t2` `t3`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003.5, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 1051.5, + "semijoin_strategy_choice": [ + { + "strategy": "LooseScan", + "recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "rows": 1, + "cost": 35, + "chosen": true + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 1299.6, + "chosen": false + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_2": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "index_handles_needed_semijoin_equalities": false + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + } + ] /* tables */ + } /* recalculate_access_paths_and_cost */, + "chosen": false + }, + { + "strategy": "DuplicatesWeedout", + "cost": 3052.5, + "rows": 10000, + "duplicate_tables_left": true, + "chosen": true + } + ] /* semijoin_strategy_choice */, + "chosen": false, + "cause": "plan_uses_disabled_strategy" + } + ] /* rest_of_plan */ + } + ] /* rest_of_plan */ + }, + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 12.996, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 100, + "cost_for_plan": 12.996, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t1`" + ] /* plan_prefix */, + "table": "`t2` `t3`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 1016, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t1`", + "`t2` `t3`" + ] /* plan_prefix */, + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 16, + "resulting_rows": 100, + "cost": 100051, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 1, + "rows_for_plan": 10000, + "cost_for_plan": 101067, + "semijoin_strategy_choice": [ + { + "strategy": "LooseScan", + "recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 12.996, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_3": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "index_handles_needed_semijoin_equalities": false + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + } + ] /* tables */ + } /* recalculate_access_paths_and_cost */, + "chosen": false + }, + { + "strategy": "DuplicatesWeedout", + "cost": 102078, + "rows": 100, + "duplicate_tables_left": true, + "chosen": true + } + ] /* semijoin_strategy_choice */, + "pruned_by_cost": true + } + ] /* rest_of_plan */ + }, + { + "plan_prefix": [ + "`t1`" + ] /* plan_prefix */, + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 1, + "rows_for_plan": 100, + "cost_for_plan": 1016, + "semijoin_strategy_choice": [ + ] /* semijoin_strategy_choice */, + "rest_of_plan": [ + { + "plan_prefix": [ + "`t1`", + "`t2`" + ] /* plan_prefix */, + "table": "`t2` `t3`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 1, + "resulting_rows": 100, + "cost": 1003.5, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 10000, + "cost_for_plan": 2019.5, + "semijoin_strategy_choice": [ + { + "strategy": "LooseScan", + "recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 12.996, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_4": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "index_handles_needed_semijoin_equalities": false + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + } + ] /* tables */ + } /* recalculate_access_paths_and_cost */, + "chosen": false + }, + { + "strategy": "DuplicatesWeedout", + "cost": 3030.5, + "rows": 100, + "duplicate_tables_left": true, + "chosen": true + } + ] /* semijoin_strategy_choice */, + "chosen": false, + "cause": "plan_uses_disabled_strategy" + } + ] /* rest_of_plan */ + } + ] /* rest_of_plan */ + }, + { + "final_semijoin_strategy": "LooseScan", + "recalculate_access_paths_and_cost": { + "tables": [ + { + "table": "`t1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "a", + "usable": false, + "chosen": false + }, + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "resulting_rows": 100, + "cost": 1299.6, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */, + "unknown_key_5": { + "searching_loose_scan_index": { + "indexes": [ + { + "index": "a", + "covering_scan": { + "cost": 1.0484, + "chosen": true + } /* covering_scan */ + } + ] /* indexes */ + } /* searching_loose_scan_index */ + } + }, + { + "table": "`t2`", + "best_access_path": { + "considered_access_paths": [ + { + "rows_to_scan": 100, + "filtering_effect": [ + ] /* filtering_effect */, + "final_filtering_effect": 1, + "access_type": "scan", + "using_join_cache": true, + "buffers_needed": 32, + "resulting_rows": 100, + "cost": 100097, + "chosen": true + } + ] /* considered_access_paths */ + } /* best_access_path */ + } + ] /* tables */ + } /* recalculate_access_paths_and_cost */ + } + ] +drop table t0,t1,t2; +# +# Discover bound equality thanks to equality propagation +# specific of ON clause. +# +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, CHARSET utf8mb4; +Warnings: +Warning 1681 Integer display width is deprecated and will be removed in a future release. +Warning 1681 Integer display width is deprecated and will be removed in a future release. +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; +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) +2 SIMPLE t1 NULL index NULL b_c_a 413 NULL 1 100.00 Using where; Using index +2 SIMPLE t3 NULL index b_c_a b_c_a 413 NULL 1 100.00 Using where; Using index; LooseScan +2 SIMPLE t2 NULL ref b_c_a b_c_a 403 test.t3.b 1 100.00 Using where; Using index +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` left join (`test`.`t1` `t2` semi join (`test`.`t1` `t3`)) on(((`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`a` = `test`.`t1`.`a`))) where (`test`.`t1`.`a` < 5) +drop table t1; +# +# Show that loosescan planning is not dependent on order of +# creation of indexes anymore. +# +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); +select * from it as ot +where (ot.a,ot.b) in (select it.a,it.b from it where it.b=3); +a b +2 3 +4 3 +select TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' +from information_schema.optimizer_trace; +TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' +0 +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); +select * from it as ot +where (ot.a,ot.b) in (select it.a,it.b from it where it.b=3); +a b +2 3 +4 3 +select TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' +from information_schema.optimizer_trace; +TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' +0 +drop table it; +# +# Show that we reject LooseScan if no handled key parts +# +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); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL ALL NULL NULL NULL NULL 1 100.00 Parallel execute (1 workers) +2 SIMPLE t3 NULL ALL NULL NULL NULL NULL 1 100.00 NULL +2 SIMPLE t2 NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Using join buffer (hash join) +2 SIMPLE t1 NULL ref a a 5 const 1 100.00 Using where; Start temporary; End temporary +Warnings: +Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` `t3` join `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = 10) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t3`.`b` = (`test`.`t1`.`b` * 3))) +SELECT TRACE LIKE '%"some_index_part_used": false%' +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +TRACE LIKE '%"some_index_part_used": false%' +1 +DROP TABLE t1,t2; +# +# Show that we detect a hole in sequence of key parts +# +CREATE TABLE ot1 (a INTEGER); +INSERT INTO ot1 VALUES (0),(1),(3),(7); +CREATE TABLE it1 (a VARCHAR(1), b INTEGER, KEY (a,b)) CHARSET utf8mb4; +INSERT INTO it1 VALUES ('a',7), ('b',7); +CREATE TABLE it2 (a VARCHAR(1), b INTEGER, KEY (a,b)) CHARSET utf8mb4; +INSERT INTO it2 VALUES ('a',7), ('b',7); +explain SELECT * FROM ot1 +WHERE a IN ( +SELECT it1.b +FROM it1 JOIN it2 +ON it1.a = it2.a +); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE it1 NULL index a a 12 NULL 2 100.00 Using index; Start temporary +1 SIMPLE ot1 NULL ALL NULL NULL NULL NULL 4 25.00 Using where; Using join buffer (hash join) +1 SIMPLE it2 NULL index a a 12 NULL 2 50.00 Using where; Using index; End temporary; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`ot1`.`a` AS `a` from `test`.`ot1` semi join (`test`.`it1` join `test`.`it2`) where ((`test`.`it2`.`a` = `test`.`it1`.`a`) and (`test`.`ot1`.`a` = `test`.`it1`.`b`)) +SELECT TRACE LIKE '%"index_can_remove_duplicates": false%' +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +TRACE LIKE '%"index_can_remove_duplicates": false%' +1 +DROP TABLE ot1, it1, it2; +# +# Show that handled keyparts cannot be on prefix +# +create table t1 (a int, b varchar(100), key a_b (a,b)) charset utf8mb4; +insert into t1 values(25,'111111'),(25,'1111112'); +explain select * from t1 as t2 where t2.b in (select b from t1 where a=25); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref a_b a_b 5 const 1 100.00 Using index; LooseScan +1 SIMPLE t2 NULL index NULL a_b 408 NULL 2 50.00 Using where; Using index; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` `t2` semi join (`test`.`t1`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = 25)) +select * from t1 as t2 where t2.b in (select b from t1 where a=25); +a b +25 111111 +25 1111112 +alter table t1 drop key a_b, add key a_b_prefix (a,b(2)); +explain select * from t1 as t2 where t2.b in (select b from t1 where a=25); +id select_type table partitions type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 NULL ref a_b_prefix a_b_prefix 5 const 1 100.00 Start temporary +1 SIMPLE t2 NULL ALL NULL NULL NULL NULL 2 50.00 Using where; End temporary; Using join buffer (hash join) +Warnings: +Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` `t2` semi join (`test`.`t1`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = 25)) +select * from t1 as t2 where t2.b in (select b from t1 where a=25); +a b +25 111111 +25 1111112 +select TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' +from information_schema.optimizer_trace; +TRACE LIKE '%"index_handles_needed_semijoin_equalities": false%' +1 +drop table t1; +set optimizer_switch=@old_opt_switch; +set optimizer_prune_level=@old_opt_prune_level; +# Tracing of CTEs using the same tmp table: observe +# "reusing_tmp_table" and only one "creating_tmp_table". +with q(a) as (select 1 union all select 2) +select * from q, q q1 where q.a=1 and q1.a=2; +a a +1 2 +select TRACE from information_schema.optimizer_trace; +TRACE +{ + "steps": [ + { + "join_preparation": { + "select#": 1, + "steps": [ + { + "join_preparation": { + "select#": 2, + "steps": [ + { + "expanded_query": "/* select#2 */ select 1 AS `1`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_preparation": { + "select#": 3, + "steps": [ + { + "expanded_query": "/* select#3 */ select 2 AS `2`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "derived": { + "table": "`q`", + "select#": 2, + "materialized": true + } /* derived */ + }, + { + "join_preparation": { + "select#": 4, + "steps": [ + { + "expanded_query": "/* select#4 */ select 1 AS `1`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_preparation": { + "select#": 5, + "steps": [ + { + "expanded_query": "/* select#5 */ select 2 AS `2`" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "derived": { + "table": "`q` `q1`", + "select#": 4, + "materialized": true, + "reusing_tmp_table": true + } /* derived */ + }, + { + "expanded_query": "/* select#1 */ select `q`.`a` AS `a`,`q1`.`a` AS `a` from `q` join `q` `q1` where ((`q`.`a` = 1) and (`q1`.`a` = 2))" + } + ] /* steps */ + } /* join_preparation */ + }, + { + "join_optimization": { + "select#": 1, + "steps": [ + { + "join_optimization": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* join_optimization */ + }, + { + "join_optimization": { + "select#": 3, + "steps": [ + ] /* steps */ + } /* join_optimization */ + }, + { + "join_optimization": { + "select#": 4, + "steps": [ + ] /* steps */ + } /* join_optimization */ + }, + { + "join_optimization": { + "select#": 5, + "steps": [ + ] /* steps */ + } /* join_optimization */ + }, + { + "condition_processing": { + "condition": "WHERE", + "original_condition": "((`q`.`a` = 1) and (`q1`.`a` = 2))", + "steps": [ + { + "transformation": "equality_propagation", + "resulting_condition": "(multiple equal(1, `q`.`a`) and multiple equal(2, `q1`.`a`))" + }, + { + "transformation": "constant_propagation", + "resulting_condition": "(multiple equal(1, `q`.`a`) and multiple equal(2, `q1`.`a`))" + }, + { + "transformation": "trivial_condition_removal", + "resulting_condition": "(multiple equal(1, `q`.`a`) and multiple equal(2, `q1`.`a`))" + } + ] /* steps */ + } /* condition_processing */ + }, + { + "substitute_generated_columns": { + } /* substitute_generated_columns */ + }, + { + "table_dependencies": [ + { + "table": "`q`", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + }, + { + "table": "`q` `q1`", + "row_may_be_null": false, + "map_bit": 1, + "depends_on_map_bits": [ + ] /* depends_on_map_bits */ + } + ] /* table_dependencies */ + }, + { + "ref_optimizer_key_uses": [ + { + "table": "`q`", + "field": "a", + "equals": "1", + "null_rejecting": false + }, + { + "table": "`q`", + "field": "a", + "equals": "1", + "null_rejecting": false + }, + { + "table": "`q` `q1`", + "field": "a", + "equals": "2", + "null_rejecting": false + }, + { + "table": "`q` `q1`", + "field": "a", + "equals": "2", + "null_rejecting": false + } + ] /* ref_optimizer_key_uses */ + }, + { + "rows_estimation": [ + { + "table": "`q`", + "table_scan": { + "rows": 2, + "cost": 2.525 + } /* table_scan */ + }, + { + "table": "`q` `q1`", + "table_scan": { + "rows": 2, + "cost": 2.525 + } /* table_scan */ + } + ] /* rows_estimation */ + }, + { + "considered_execution_plans": [ + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`q`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "", + "rows": 1, + "cost": 0.35, + "chosen": true + }, + { + "access_type": "ref", + "index": "", + "rows": 1, + "cost": 0.35, + "chosen": false + }, + { + "access_type": "scan", + "cost": 2.725, + "rows": 2, + "chosen": false, + "cause": "cost" + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 1, + "cost_for_plan": 0.35, + "rest_of_plan": [ + { + "plan_prefix": [ + "`q`" + ] /* plan_prefix */, + "table": "`q` `q1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "", + "rows": 1, + "cost": 0.35, + "chosen": true + }, + { + "access_type": "ref", + "index": "", + "rows": 1, + "cost": 0.35, + "chosen": false + }, + { + "access_type": "scan", + "cost": 2.725, + "rows": 2, + "chosen": false, + "cause": "cost" + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 1, + "cost_for_plan": 0.7, + "chosen": true + } + ] /* rest_of_plan */ + }, + { + "plan_prefix": [ + ] /* plan_prefix */, + "table": "`q` `q1`", + "best_access_path": { + "considered_access_paths": [ + { + "access_type": "ref", + "index": "", + "rows": 1, + "cost": 0.35, + "chosen": true + }, + { + "access_type": "ref", + "index": "", + "rows": 1, + "cost": 0.35, + "chosen": false + }, + { + "access_type": "scan", + "cost": 2.725, + "rows": 2, + "chosen": false, + "cause": "cost" + } + ] /* considered_access_paths */ + } /* best_access_path */, + "condition_filtering_pct": 100, + "rows_for_plan": 1, + "cost_for_plan": 0.35, + "pruned_by_heuristic": true + } + ] /* considered_execution_plans */ + }, + { + "attaching_conditions_to_tables": { + "original_condition": "((`q1`.`a` = 2) and (`q`.`a` = 1))", + "attached_conditions_computation": [ + ] /* attached_conditions_computation */, + "attached_conditions_summary": [ + { + "table": "`q`", + "attached": "(`q`.`a` = 1)" + }, + { + "table": "`q` `q1`", + "attached": "(`q1`.`a` = 2)" + } + ] /* attached_conditions_summary */ + } /* attaching_conditions_to_tables */ + }, + { + "finalizing_table_conditions": [ + { + "table": "`q`", + "original_table_condition": "(`q`.`a` = 1)", + "final_table_condition ": null + }, + { + "table": "`q` `q1`", + "original_table_condition": "(`q1`.`a` = 2)", + "final_table_condition ": null + } + ] /* finalizing_table_conditions */ + }, + { + "refine_plan": [ + { + "table": "`q`" + }, + { + "table": "`q` `q1`" + } + ] /* refine_plan */ + } + ] /* steps */ + } /* join_optimization */ + }, + { + "join_execution": { + "select#": 1, + "steps": [ + { + "creating_tmp_table": { + "tmp_table_info": { + "table": "`q`", + "in_plan_at_position": 0, + "columns": 1, + "row_length": 9, + "key_length": 8, + "unique_constraint": false, + "makes_grouped_rows": false, + "cannot_insert_duplicates": false, + "location": "TempTable" + } /* tmp_table_info */ + } /* creating_tmp_table */ + }, + { + "materialize": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* materialize */ + }, + { + "materialize": { + "select#": 3, + "steps": [ + ] /* steps */ + } /* materialize */ + } + ] /* steps */ + } /* join_execution */ + } + ] /* steps */ +} +# Tracing of repetitions of the recursive member +# can be silenced with repeated_subselect=off +with recursive qn(n) as +(select 1 union all select n+1 from qn where n<4) +select count(*) from qn; +count(*) +4 +SELECT show_json_object('"join_execution": {', TRACE) +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +show_json_object('"join_execution": {', TRACE) +"join_execution": { + "select#": 1, + "steps": [ + { + "creating_tmp_table": { + "tmp_table_info": { + "table": "`qn`", + "in_plan_at_position": 0, + "columns": 1, + "row_length": 9, + "key_length": 0, + "unique_constraint": false, + "makes_grouped_rows": false, + "cannot_insert_duplicates": false, + "location": "TempTable" + } /* tmp_table_info */ + } /* creating_tmp_table */ + }, + { + "materialize": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* materialize */ + }, + { + "materialize": { + "select#": 3, + "steps": [ + ] /* steps */ + } /* materialize */ + }, + { + "materialize": { + "select#": 3, + "steps": [ + ] /* steps */ + } /* materialize */ + } + ] /* steps */ + } +SET @@optimizer_trace_features="repeated_subselect=off"; +with recursive qn(n) as +(select 1 union all select n+1 from qn where n<4) +select count(*) from qn; +count(*) +4 +SELECT show_json_object('"join_execution": {', TRACE) +FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; +show_json_object('"join_execution": {', TRACE) +"join_execution": { + "select#": 1, + "steps": [ + { + "creating_tmp_table": { + "tmp_table_info": { + "table": "`qn`", + "in_plan_at_position": 0, + "columns": 1, + "row_length": 9, + "key_length": 0, + "unique_constraint": false, + "makes_grouped_rows": false, + "cannot_insert_duplicates": false, + "location": "TempTable" + } /* tmp_table_info */ + } /* creating_tmp_table */ + }, + { + "materialize": { + "select#": 2, + "steps": [ + ] /* steps */ + } /* materialize */ + }, + { + "materialize": { + "select#": 3, + "steps": [ + ] /* steps */ + } /* materialize */ + } + ] /* steps */ + } +SET @@optimizer_trace_features=default; +drop function show_json_object; diff --git a/sql/pq_clone.cc b/sql/pq_clone.cc index 39a87dddf70b..c0fb9ad40b4e 100644 --- a/sql/pq_clone.cc +++ b/sql/pq_clone.cc @@ -81,7 +81,7 @@ bool QEP_TAB::pq_copy(THD *thd, QEP_TAB *orig) { do_parallel_scan = orig->do_parallel_scan; firstmatch_return = orig->firstmatch_return; cache_idx_cond = orig->cache_idx_cond; - + loosescan_key_len = orig->loosescan_key_len; POSITION *position = new (thd->pq_mem_root) POSITION; if (!position || position->pq_copy(thd, orig->position())) return true; diff --git a/sql/pq_clone_item.cc b/sql/pq_clone_item.cc index 177e1aa991c4..46f4f698ec56 100644 --- a/sql/pq_clone_item.cc +++ b/sql/pq_clone_item.cc @@ -225,7 +225,7 @@ PQ_CLONE_RETURN /* Item_hex_string start */ PQ_CLONE_DEF(Item_hex_string) { - new_item = new (thd->mem_root) Item_hex_string(POS()); + new_item = new (thd->pq_mem_root) Item_hex_string(POS()); } PQ_CLONE_RETURN @@ -550,7 +550,7 @@ PQ_CLONE_DEF(Item_func_max) { PT_item_list pt_item_list; pt_item_list.value = item_list; - new_item = new (thd->mem_root) Item_func_max(POS(), &pt_item_list); + new_item = new (thd->pq_mem_root) Item_func_max(POS(), &pt_item_list); } PQ_CLONE_RETURN @@ -560,7 +560,7 @@ PQ_CLONE_DEF(Item_func_min) { PT_item_list pt_item_list; pt_item_list.value = item_list; - new_item = new (thd->mem_root) Item_func_min(POS(), &pt_item_list); + new_item = new (thd->pq_mem_root) Item_func_min(POS(), &pt_item_list); } PQ_CLONE_RETURN /* Item_func_min_max end */ @@ -601,7 +601,7 @@ PQ_CLONE_DEF(Item_func_regexp_like) { PT_item_list pt_item_list; pt_item_list.value = item_list; - new_item = new (thd->mem_root) Item_func_regexp_like(POS(), &pt_item_list); + new_item = new (thd->pq_mem_root) Item_func_regexp_like(POS(), &pt_item_list); } PQ_CLONE_RETURN /* Item_func_regexp end */ @@ -609,7 +609,7 @@ PQ_CLONE_RETURN /* Item_func_weekday start */ PQ_CLONE_DEF(Item_func_weekday) { PQ_CLONE_ARGS - new_item = new (thd->mem_root) + new_item = new (thd->pq_mem_root) Item_func_weekday(POS(), item_list[0], this->odbc_type); } PQ_CLONE_RETURN @@ -793,7 +793,7 @@ PQ_CLONE_DEF(Item_func_field) { PT_item_list pt_item_list; pt_item_list.value = item_list; - new_item = new (thd->mem_root) Item_func_field(POS(), &pt_item_list); + new_item = new (thd->pq_mem_root) Item_func_field(POS(), &pt_item_list); } PQ_CLONE_RETURN @@ -1048,7 +1048,7 @@ COPY_FUNC_ITEM(Item_func_conv_charset, POS(), ARG0, conv_charset) PQ_CLONE_DEF(Item_func_date_format) { PQ_CLONE_ARGS - new_item = new (thd->mem_root) Item_func_date_format( + new_item = new (thd->pq_mem_root) Item_func_date_format( POS(), item_list[0], item_list[1], this->is_time_format); } PQ_CLONE_RETURN @@ -1067,7 +1067,7 @@ PQ_CLONE_DEF(Item_func_elt) { PT_item_list pt_item_list; pt_item_list.value = item_list; - new_item = new (thd->mem_root) Item_func_elt(POS(), &pt_item_list); + new_item = new (thd->pq_mem_root) Item_func_elt(POS(), &pt_item_list); } PQ_CLONE_RETURN @@ -1255,7 +1255,7 @@ COPY_FUNC_ITEM(Item_func_random_bytes, POS(), ARG0) PQ_CLONE_DEF(Item_func_right) { PQ_CLONE_ARGS new_item = - new (thd->mem_root) Item_func_right(POS(), item_list[0], item_list[1]); + new (thd->pq_mem_root) Item_func_right(POS(), item_list[0], item_list[1]); } PQ_CLONE_RETURN @@ -1307,11 +1307,11 @@ PQ_CLONE_DEF(Item_func_trim) { PQ_CLONE_ARGS if (arg_count > 1) - new_item = new (thd->mem_root) + new_item = new (thd->pq_mem_root) Item_func_trim(POS(), item_list[0], item_list[1], m_trim_mode); else new_item = - new (thd->mem_root) Item_func_trim(POS(), item_list[0], m_trim_mode); + new (thd->pq_mem_root) Item_func_trim(POS(), item_list[0], m_trim_mode); } PQ_CLONE_RETURN @@ -1493,7 +1493,7 @@ PQ_COPY_FROM_RETURN PQ_CLONE_DEF(Item_func_curtime_local) { PQ_CLONE_ARGS - new_item = new (thd->mem_root) Item_func_curtime_local(POS(), this->decimals); + new_item = new (thd->pq_mem_root) Item_func_curtime_local(POS(), this->decimals); } PQ_CLONE_RETURN @@ -1601,7 +1601,7 @@ PQ_CLONE_DEF(Item_sum_and) { Item *arg = args[0]->pq_clone(thd, select); if (nullptr == arg) return nullptr; - new_item = new (thd->mem_root) Item_sum_and(POS(), arg, nullptr); + new_item = new (thd->pq_mem_root) Item_sum_and(POS(), arg, nullptr); } PQ_CLONE_RETURN @@ -1614,7 +1614,7 @@ PQ_CLONE_DEF(Item_sum_or) { Item *arg = args[0]->pq_clone(thd, select); if (nullptr == arg) return nullptr; - new_item = new (thd->mem_root) Item_sum_or(POS(), arg, nullptr); + new_item = new (thd->pq_mem_root) Item_sum_or(POS(), arg, nullptr); } PQ_CLONE_RETURN @@ -1627,7 +1627,7 @@ PQ_CLONE_DEF(Item_sum_xor) { Item *arg = args[0]->pq_clone(thd, select); if (nullptr == arg) return nullptr; - new_item = new (thd->mem_root) Item_sum_xor(POS(), arg, nullptr); + new_item = new (thd->pq_mem_root) Item_sum_xor(POS(), arg, nullptr); } PQ_CLONE_RETURN @@ -1841,7 +1841,7 @@ PQ_CLONE_DEF(Item_func_trig_cond) { if (arg_count > 0) arg = args[0]->pq_clone(thd, select); if (nullptr == arg) return nullptr; - new_item = new(thd->mem_root) Item_func_trig_cond(arg, trig_var, thd->lex->unit->first_select()->join, m_idx,trig_type); + new_item = new(thd->pq_mem_root) Item_func_trig_cond(arg, trig_var, thd->lex->unit->first_select()->join, m_idx,trig_type); } PQ_CLONE_RETURN