Skip to content

Commit 5d9500b

Browse files
author
Guilhem Bichot
committed
Bug#31376809 PERFORMANCE REGRESSION FROM 5.7->8.0, DUE TO ANTIJOIN OF NOT EXISTS SUBQUERY
Disable antijoin transformation if this is: - NOT EXISTS, or <constant> NOT IN, - and the subquery is not correlated. Otherwise we got this type of plan: nested loop antijoin -> outer -> inner and we would read each row of "outer", only to find, every time, that there is a row in "inner" and that we should not emit the row of "outer". Instead, we evaluate the subquery during optimization, leading to an always true or false condition. This does not cancel Steinar's patch for the same bug report; however it makes "case 2" (see his commit comment) apply only to antijoin coming from LEFT JOIN, as antijoin coming from NOT EXISTS will not reach the executor anymore, due to the present patch. Approved by: Roy Lyseng <[email protected]> Change-Id: I59a887456a56039a6b1480b3ec8f7ac188d1ce58
1 parent ca0aa69 commit 5d9500b

10 files changed

+118
-80
lines changed

mysql-test/r/innodb_icp_all.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -715,14 +715,14 @@ AND 6=7
715715
)
716716
;;
717717
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
718-
1 PRIMARY t1a NULL ALL NULL NULL NULL NULL 1 100.00 NULL
719-
1 PRIMARY t1b NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Not exists; Using join buffer (hash join)
718+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
719+
2 SUBQUERY t1b NULL ALL NULL NULL NULL NULL 1 100.00 Using where
720720
3 DEPENDENT SUBQUERY t2 NULL unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where; Full scan on NULL key
721721
Warnings:
722722
Note 1276 Field or reference 'test.t1b.t1_time' of SELECT #3 was resolved in SELECT #2
723723
Note 1276 Field or reference 'test.t1b.t1_int' of SELECT #3 was resolved in SELECT #2
724724
Note 1276 Field or reference 'test.t1b.t1_time' of SELECT #3 was resolved in SELECT #2
725-
Note 1003 /* select#1 */ select `test`.`t1a`.`t1_int` AS `t1_int`,`test`.`t1a`.`t1_time` AS `t1_time` from `test`.`t1` `t1a` anti join (`test`.`t1` `t1b`) on((<in_optimizer>(`test`.`t1b`.`t1_int`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1b`.`t1_int`) in t2 on PRIMARY where ((`test`.`t1b`.`t1_time` like `test`.`t1b`.`t1_int`) and <if>(outer_field_is_not_null, (<cache>(`test`.`t1b`.`t1_int`) = `test`.`t2`.`t2_int`), true)))) is false))) where true
725+
Note 1003 /* select#1 */ select `test`.`t1a`.`t1_int` AS `t1_int`,`test`.`t1a`.`t1_time` AS `t1_time` from `test`.`t1` `t1a` where false
726726

727727
DROP TABLE t1,t2;
728728
#

mysql-test/r/myisam_icp_all.result

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -713,14 +713,14 @@ AND 6=7
713713
)
714714
;;
715715
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
716-
1 PRIMARY t1a NULL system NULL NULL NULL NULL 1 100.00 NULL
717-
1 PRIMARY t1b NULL ALL NULL NULL NULL NULL 1 100.00 Using where; Not exists
718-
3 DEPENDENT SUBQUERY t2 NULL system PRIMARY NULL NULL NULL 1 100.00 NULL
716+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
717+
2 SUBQUERY t1b NULL system NULL NULL NULL NULL 1 100.00 NULL
718+
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
719719
Warnings:
720720
Note 1276 Field or reference 'test.t1b.t1_time' of SELECT #3 was resolved in SELECT #2
721721
Note 1276 Field or reference 'test.t1b.t1_int' of SELECT #3 was resolved in SELECT #2
722722
Note 1276 Field or reference 'test.t1b.t1_time' of SELECT #3 was resolved in SELECT #2
723-
Note 1003 /* select#1 */ select NULL AS `t1_int`,NULL AS `t1_time` from <constant table> anti join (`test`.`t1` `t1b`) on((<in_optimizer>(`test`.`t1b`.`t1_int`,<exists>(/* select#3 */ select '0' from dual where ((`test`.`t1b`.`t1_time` like `test`.`t1b`.`t1_int`) and <if>(outer_field_is_not_null, (<cache>(`test`.`t1b`.`t1_int`) = '0'), true))) is false))) where true
723+
Note 1003 /* select#1 */ select `test`.`t1a`.`t1_int` AS `t1_int`,`test`.`t1a`.`t1_time` AS `t1_time` from `test`.`t1` `t1a` where false
724724

725725
DROP TABLE t1,t2;
726726
#

mysql-test/r/subquery_all.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5335,12 +5335,12 @@ SELECT COUNT(*) FROM t1
53355335
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
53365336
ORDER BY COUNT(*);
53375337
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
5338-
1 PRIMARY t1 NULL index NULL a 5 NULL 2 100.00 Using index
5339-
1 PRIMARY t2 NULL ALL NULL NULL NULL NULL 2 100.00 Using where; Not exists; Using join buffer (hash join)
5338+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
5339+
2 SUBQUERY t2 NULL ALL NULL NULL NULL NULL 2 100.00 Using where
53405340
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
53415341
Warnings:
53425342
Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2
5343-
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` anti join (`test`.`t2`) on(((1 = (/* select#3 */ select min(`test`.`t2`.`b`) from `test`.`t3`)))) where true
5343+
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` where true
53445344
# should not crash the next statement
53455345
SELECT COUNT(*) FROM t1
53465346
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))

mysql-test/r/subquery_all_bka.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5336,12 +5336,12 @@ SELECT COUNT(*) FROM t1
53365336
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
53375337
ORDER BY COUNT(*);
53385338
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
5339-
1 PRIMARY t1 NULL index NULL a 5 NULL 2 100.00 Using index
5340-
1 PRIMARY t2 NULL ALL NULL NULL NULL NULL 2 100.00 Using where; Not exists; Using join buffer (hash join)
5339+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
5340+
2 SUBQUERY t2 NULL ALL NULL NULL NULL NULL 2 100.00 Using where
53415341
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
53425342
Warnings:
53435343
Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2
5344-
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` anti join (`test`.`t2`) on(((1 = (/* select#3 */ select min(`test`.`t2`.`b`) from `test`.`t3`)))) where true
5344+
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` where true
53455345
# should not crash the next statement
53465346
SELECT COUNT(*) FROM t1
53475347
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))

mysql-test/r/subquery_all_bka_nobnl.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5336,12 +5336,12 @@ SELECT COUNT(*) FROM t1
53365336
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
53375337
ORDER BY COUNT(*);
53385338
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
5339-
1 PRIMARY t1 NULL index NULL a 5 NULL 2 100.00 Using index
5340-
1 PRIMARY t2 NULL ALL NULL NULL NULL NULL 2 100.00 Using where; Not exists
5339+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
5340+
2 SUBQUERY t2 NULL ALL NULL NULL NULL NULL 2 100.00 Using where
53415341
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
53425342
Warnings:
53435343
Note 1276 Field or reference 'test.t2.b' of SELECT #3 was resolved in SELECT #2
5344-
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` anti join (`test`.`t2`) on(((1 = (/* select#3 */ select min(`test`.`t2`.`b`) from `test`.`t3`)))) where true
5344+
Note 1003 /* select#1 */ select count(0) AS `COUNT(*)` from `test`.`t1` where true
53455345
# should not crash the next statement
53465346
SELECT COUNT(*) FROM t1
53475347
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))

mysql-test/r/subquery_antijoin.result

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ a
4141
EXPLAIN SELECT 1 as a FROM t2 as ot
4242
WHERE NOT EXISTS (SELECT * FROM t1 AS it);
4343
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
44-
1 SIMPLE ot NULL index NULL PRIMARY 4 NULL 80 100.00 Using index
45-
1 SIMPLE it NULL index NULL ukn 4 NULL 3 100.00 Using where; Not exists; Using index; Using join buffer (hash join)
44+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
45+
2 SUBQUERY it NULL index NULL ukn 4 NULL 3 100.00 Using index
4646
Warnings:
47-
Note 1003 /* select#1 */ select 1 AS `a` from `test`.`t2` `ot` anti join (`test`.`t1` `it`) on((1 = 1)) where true
47+
Note 1003 /* select#1 */ select 1 AS `a` from `test`.`t2` `ot` where false
4848
SELECT 1 as a FROM t2 as ot
4949
WHERE NOT EXISTS (SELECT * FROM t1 AS it);
5050
a
@@ -177,11 +177,10 @@ a
177177
EXPLAIN SELECT 1 as a FROM t2 as ot
178178
WHERE NOT EXISTS (SELECT * FROM t1 AS it);
179179
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
180-
1 SIMPLE ot NULL index NULL PRIMARY 4 NULL 80 100.00 Using index
181-
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
182-
2 MATERIALIZED it NULL index NULL ukn 4 NULL 3 100.00 Using where; Using index
180+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
181+
2 SUBQUERY it NULL index NULL ukn 4 NULL 3 100.00 Using index
183182
Warnings:
184-
Note 1003 /* select#1 */ select 1 AS `a` from `test`.`t2` `ot` anti join (`test`.`t1` `it`) on((1 = 1)) where true
183+
Note 1003 /* select#1 */ select 1 AS `a` from `test`.`t2` `ot` where false
185184
SELECT 1 as a FROM t2 as ot
186185
WHERE NOT EXISTS (SELECT * FROM t1 AS it);
187186
a
@@ -469,11 +468,10 @@ Warnings:
469468
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t1` `t3`) where true
470469
EXPLAIN SELECT * FROM t1 WHERE NOT EXISTS(SELECT * FROM t1 t3);
471470
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
472-
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
473-
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
474-
2 MATERIALIZED t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where
471+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
472+
2 SUBQUERY t3 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
475473
Warnings:
476-
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` anti join (`test`.`t1` `t3`) on((1 = 1)) where true
474+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where false
477475
EXPLAIN SELECT * FROM t1 WHERE EXISTS(SELECT * FROM t1 t3) IS TRUE;
478476
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
479477
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 NULL
@@ -483,11 +481,10 @@ Warnings:
483481
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t1` `t3`) where true
484482
EXPLAIN SELECT * FROM t1 WHERE EXISTS(SELECT * FROM t1 t3) IS FALSE;
485483
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
486-
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
487-
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
488-
2 MATERIALIZED t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where
484+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
485+
2 SUBQUERY t3 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
489486
Warnings:
490-
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` anti join (`test`.`t1` `t3`) on((1 = 1)) where true
487+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where false
491488
EXPLAIN SELECT * FROM t1 WHERE EXISTS(SELECT * FROM t1 t3) IS UNKNOWN;
492489
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
493490
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
@@ -496,11 +493,10 @@ Warnings:
496493
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where false
497494
EXPLAIN SELECT * FROM t1 WHERE EXISTS(SELECT * FROM t1 t3) IS NOT TRUE;
498495
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
499-
1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
500-
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
501-
2 MATERIALIZED t3 NULL ALL NULL NULL NULL NULL 3 100.00 Using where
496+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
497+
2 SUBQUERY t3 NULL ALL NULL NULL NULL NULL 3 100.00 NULL
502498
Warnings:
503-
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` anti join (`test`.`t1` `t3`) on((1 = 1)) where true
499+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where false
504500
EXPLAIN SELECT * FROM t1 WHERE EXISTS(SELECT * FROM t1 t3) IS NOT FALSE;
505501
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
506502
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 NULL
@@ -656,13 +652,12 @@ subquery2_t1.col_varchar_key >= '2'
656652
) AND
657653
t1.pk IN (2);
658654
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
659-
1 SIMPLE t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL
660-
1 SIMPLE <subquery2> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
661-
2 MATERIALIZED subquery2_t1 NULL index idx_cc_col_varchar_key idx_cc_col_varchar_key 7 NULL 1 100.00 Using index
662-
2 MATERIALIZED subquery2_t2 NULL index NULL idx_cc_col_varchar_key 7 NULL 1 100.00 Using where; Using index; Using join buffer (hash join)
663-
2 MATERIALIZED subquery2_t3 NULL index NULL idx_cc_col_varchar_key 7 NULL 1 100.00 Using index; Using join buffer (hash join)
655+
1 PRIMARY t1 NULL const PRIMARY PRIMARY 4 const 1 100.00 NULL
656+
2 SUBQUERY subquery2_t1 NULL index idx_cc_col_varchar_key idx_cc_col_varchar_key 7 NULL 1 100.00 Using index
657+
2 SUBQUERY subquery2_t2 NULL index NULL idx_cc_col_varchar_key 7 NULL 1 100.00 Using where; Using index; Using join buffer (hash join)
658+
2 SUBQUERY subquery2_t3 NULL index NULL idx_cc_col_varchar_key 7 NULL 1 100.00 Using index; Using join buffer (hash join)
664659
Warnings:
665-
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2` FIRSTMATCH) */ 'a' AS `col_varchar_key` from `test`.`t1` anti join (`test`.`t2` `subquery2_t1` left join (`test`.`t1` `subquery2_t2` join `test`.`t1` `subquery2_t3`) on((true))) on((((`test`.`subquery2_t2`.`col_varchar_key` <> `test`.`subquery2_t1`.`col_varchar_key`) or (`test`.`subquery2_t1`.`col_varchar_key` >= '2')))) where true
660+
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2` FIRSTMATCH) */ 'a' AS `col_varchar_key` from `test`.`t1` where true
666661
SELECT col_varchar_key FROM t1
667662
WHERE NOT EXISTS
668663
(SELECT /*+ NO_SEMIJOIN(FIRSTMATCH) */
@@ -723,14 +718,14 @@ WHERE NOT EXISTS (SELECT pk FROM t1 AS sj1)
723718
ON alias3.pk = alias1.col_int AND
724719
NOT EXISTS (SELECT * FROM t1 AS sj2 WHERE (SELECT 1) IS NULL);
725720
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
726-
1 SIMPLE alias1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL
727-
1 SIMPLE t1 NULL index NULL PRIMARY 4 NULL 1 100.00 Using index
728-
1 SIMPLE alias2 NULL eq_ref PRIMARY PRIMARY 4 test.alias1.col_int 1 100.00 Using index
729-
1 SIMPLE <subquery3> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
730-
3 MATERIALIZED sj1 NULL index NULL PRIMARY 4 NULL 1 100.00 Using where; Using index
721+
1 PRIMARY alias1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL
722+
1 PRIMARY t1 NULL index NULL PRIMARY 4 NULL 1 100.00 Using where; Using index
723+
1 PRIMARY alias2 NULL eq_ref PRIMARY PRIMARY 4 test.alias1.col_int 1 100.00 Using index
724+
4 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
725+
3 SUBQUERY sj1 NULL index NULL PRIMARY 4 NULL 1 100.00 Using index
731726
Warnings:
732727
Note 1249 Select 5 was reduced during optimization
733-
Note 1003 /* select#1 */ select `test`.`alias1`.`pk` AS `pk` from `test`.`t1` `alias1` left join (`test`.`t1` join `test`.`t1` `alias2` anti join (`test`.`t1` `sj1`) on(true)) on(((`test`.`alias2`.`pk` = `test`.`alias1`.`col_int`))) where true
728+
Note 1003 /* select#1 */ select `test`.`alias1`.`pk` AS `pk` from `test`.`t1` `alias1` left join (`test`.`t1` join `test`.`t1` `alias2`) on(((`test`.`alias2`.`pk` = `test`.`alias1`.`col_int`) and exists(/* select#4 */ select 1 from `test`.`t1` `sj2` where false) is false and exists(/* select#3 */ select `test`.`sj1`.`pk` from `test`.`t1` `sj1`) is false)) where true
734729
SELECT alias1.pk
735730
FROM t1 AS alias1 LEFT JOIN
736731
(SELECT alias2.*
@@ -905,25 +900,26 @@ NOT EXISTS ( SELECT * FROM t1 as t4);
905900
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
906901
1 PRIMARY t1 NULL ALL NULL NULL NULL NULL 1 100.00 NULL
907902
1 PRIMARY t2 NULL ALL NULL NULL NULL NULL 1 100.00 Using where
908-
1 PRIMARY <subquery3> NULL const <auto_distinct_key> <auto_distinct_key> 8 const 1 100.00 Using where; Not exists
909-
3 MATERIALIZED t4 NULL index NULL PRIMARY 4 NULL 1 100.00 Using where; Using index
903+
3 SUBQUERY t4 NULL index NULL PRIMARY 4 NULL 1 100.00 Using index
910904
2 UNCACHEABLE SUBQUERY t3 NULL index NULL PRIMARY 4 NULL 1 100.00 Using index
911905
Warnings:
912-
Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`col_int` AS `col_int`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`col_int` AS `col_int` from `test`.`t1` left join (`test`.`t1` `t2` anti join (`test`.`t1` `t4`) on((1 = 1))) on(((`test`.`t1`.`col_int` > (/* select#2 */ select (@`var`) from `test`.`t1` `t3`)) and true)) where true
906+
Note 1003 /* select#1 */ select `test`.`t1`.`pk` AS `pk`,`test`.`t1`.`col_int` AS `col_int`,`test`.`t2`.`pk` AS `pk`,`test`.`t2`.`col_int` AS `col_int` from `test`.`t1` left join `test`.`t1` `t2` on(((`test`.`t1`.`col_int` > (/* select#2 */ select (@`var`) from `test`.`t1` `t3`)) and exists(/* select#3 */ select 1 from `test`.`t1` `t4`) is false)) where true
913907
EXPLAIN FORMAT=TREE SELECT * FROM t1 LEFT JOIN t1 AS t2
914908
ON 1 AND t1.col_int > ( SELECT @var FROM t1 as t3 ) AND
915909
NOT EXISTS ( SELECT * FROM t1 as t4);
916910
EXPLAIN
917-
-> Nested loop left join
911+
-> Nested loop left join (cost=0.70 rows=1)
918912
-> Table scan on t1 (cost=0.35 rows=1)
919-
-> Filter: (t1.col_int > (select #2))
920-
-> Nested loop antijoin
921-
-> Table scan on t2 (cost=0.35 rows=1)
922-
-> Constant row from <subquery3>
923-
-> Materialize with deduplication
924-
-> Index scan on t4 using PRIMARY (cost=0.35 rows=1)
913+
-> Filter: (exists(select #3) is false and ((t1.col_int > (select #2)) and exists(select #3) is false)) (cost=0.35 rows=1)
914+
-> Table scan on t2 (cost=0.35 rows=1)
915+
-> Select #3 (subquery in condition; run only once)
916+
-> Limit: 1 row(s)
917+
-> Index scan on t4 using PRIMARY (cost=0.35 rows=1)
925918
-> Select #2 (subquery in condition; uncacheable)
926919
-> Index scan on t3 using PRIMARY (cost=0.35 rows=1)
920+
-> Select #3 (subquery in condition; run only once)
921+
-> Limit: 1 row(s)
922+
-> Index scan on t4 using PRIMARY (cost=0.35 rows=1)
927923

928924
SELECT * FROM t1 LEFT JOIN t1 AS t2
929925
ON 1 AND t1.col_int > ( SELECT @var FROM t1 as t3 ) AND
@@ -1010,11 +1006,12 @@ alias1.col_datetime_key AS field3
10101006
FROM t1 AS alias1 LEFT JOIN t1 AS alias2
10111007
ON NOT EXISTS ( SELECT * FROM t1 AS alias3 WHERE ( SELECT 1 FROM DUAL ) IS NULL );
10121008
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1013-
1 SIMPLE alias1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
1014-
1 SIMPLE alias2 NULL index NULL idx_C_col_varchar_key 6 NULL 2 100.00 Using where; Using index; Using join buffer (hash join)
1009+
1 PRIMARY alias1 NULL ALL NULL NULL NULL NULL 2 100.00 NULL
1010+
1 PRIMARY alias2 NULL index NULL idx_C_col_varchar_key 6 NULL 2 100.00 Using where; Using index; Using join buffer (hash join)
1011+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
10151012
Warnings:
10161013
Note 1249 Select 3 was reduced during optimization
1017-
Note 1003 /* select#1 */ select `test`.`alias1`.`col_int` AS `field1`,`test`.`alias2`.`col_varchar_key` AS `field2`,`test`.`alias1`.`col_datetime_key` AS `field3` from `test`.`t1` `alias1` left join `test`.`t1` `alias2` on(true) where true
1014+
Note 1003 /* select#1 */ select `test`.`alias1`.`col_int` AS `field1`,`test`.`alias2`.`col_varchar_key` AS `field2`,`test`.`alias1`.`col_datetime_key` AS `field3` from `test`.`t1` `alias1` left join `test`.`t1` `alias2` on(exists(/* select#2 */ select 1 from `test`.`t1` `alias3` where false) is false) where true
10181015
SELECT alias1.col_int AS field1 , alias2.col_varchar_key AS field2 ,
10191016
alias1.col_datetime_key AS field3
10201017
FROM t1 AS alias1 LEFT JOIN t1 AS alias2
@@ -1081,3 +1078,21 @@ SELECT MAX(t1.a) FROM t1 WHERE a NOT IN (SELECT a FROM t2);
10811078
MAX(t1.a)
10821079
1
10831080
DROP TABLE t1, t2;
1081+
#
1082+
# Bug#31376809 PERFORMANCE REGRESSION FROM 5.7->8.0, DUE TO ANTIJOIN OF NOT EXISTS SUBQUERY
1083+
#
1084+
create table t(a int, b int);
1085+
insert into t values(1,1),(2,2),(3,3),(4,4),(5,5);
1086+
explain format=tree select a from t where (not exists (select b from t));
1087+
EXPLAIN
1088+
-> Zero rows (Impossible WHERE)
1089+
1090+
select a from t where (not exists (select b from t));
1091+
a
1092+
explain format=tree select a from t where 1 not in (select 1 from t);
1093+
EXPLAIN
1094+
-> Zero rows (Impossible WHERE)
1095+
1096+
select a from t where 1 not in (select 1 from t);
1097+
a
1098+
drop table t;

0 commit comments

Comments
 (0)