Commit 599a1384 authored by unknown's avatar unknown

Fix for MDEV-4144

  
Analysis:
The reason for the inefficent plan was that Item_subselect::is_expensive()
didn't detect the special case when a subquery was optimized, but had no
join plan because it either has no table, or its tables have been optimized
away, or the optimizer detected that the result set is empty.
  
Solution:
Identify the special cases above in the Item_subselect::is_expensive(),
and consider such degenerate subqueries inexpensive.
parent fa01b76b
...@@ -1837,10 +1837,10 @@ INSERT INTO t2 VALUES ...@@ -1837,10 +1837,10 @@ INSERT INTO t2 VALUES
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings: Warnings:
Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where (<cache>(<in_optimizer>((1,2),<exists>(select 3,4 having (((1 = 3) or isnull(3)) and ((2 = 4) or isnull(4)) and <is_not_null_test>(3) and <is_not_null_test>(4))))) and (`test`.`t1`.`a` < 10)) Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10;
MAX(a) MAX(a)
NULL NULL
......
...@@ -120,7 +120,7 @@ create table t1 (a int primary key); ...@@ -120,7 +120,7 @@ create table t1 (a int primary key);
insert into t1 values (1); insert into t1 values (1);
explain select * from t1 where 3 in (select (1+1) union select 1); explain select * from t1 where 3 in (select (1+1) union select 1);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
......
...@@ -429,7 +429,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -429,7 +429,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1)) Note 1003 select 1 AS `1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment, `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
...@@ -558,10 +558,10 @@ Warnings: ...@@ -558,10 +558,10 @@ Warnings:
Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1') Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'); EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')))) Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((1 = '1'))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -1371,7 +1371,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal ...@@ -1371,7 +1371,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000); insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1); explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where 1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`)) Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
......
...@@ -869,7 +869,7 @@ NULL ...@@ -869,7 +869,7 @@ NULL
EXPLAIN EXPLAIN
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
f1 f2 f1 f2
...@@ -960,7 +960,7 @@ NULL ...@@ -960,7 +960,7 @@ NULL
EXPLAIN EXPLAIN
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2);
f1 f2 f1 f2
...@@ -1055,7 +1055,7 @@ NULL ...@@ -1055,7 +1055,7 @@ NULL
EXPLAIN EXPLAIN
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
f1 f2 f1 f2
...@@ -1146,7 +1146,7 @@ NULL ...@@ -1146,7 +1146,7 @@ NULL
EXPLAIN EXPLAIN
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10); SELECT * FROM t1 WHERE (2, 0) NOT IN (SELECT min(f3)+f3, min(f4)+f3+max(f4) FROM t2 WHERE f3 > 10);
f1 f2 f1 f2
...@@ -2012,7 +2012,7 @@ FROM t2 JOIN t3 ON t3.f4 = t2.f4 ...@@ -2012,7 +2012,7 @@ FROM t2 JOIN t3 ON t3.f4 = t2.f4
WHERE t3.f1 = 8 WHERE t3.f1 = 8
GROUP BY 1, 2; GROUP BY 1, 2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 system NULL NULL NULL NULL 1 Using temporary; Using filesort 1 PRIMARY t3 system NULL NULL NULL NULL 1 Using filesort
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table 3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
...@@ -2325,5 +2325,19 @@ ORDER BY alias1.b; ...@@ -2325,5 +2325,19 @@ ORDER BY alias1.b;
pk b pk b pk b pk b
1 1 1 1 1 1 1 1
drop table t1, t2, t3; drop table t1, t2, t3;
#
# MDEV-4144 simple subquery causes full scan instead of range scan
#
CREATE TABLE t1 (id int not null auto_increment, x int not null, primary key(id));
INSERT INTO t1 (x) VALUES (0),(0),(0);
EXPLAIN
SELECT x FROM t1 WHERE id > (SELECT MAX(id) - 1000 FROM t1) ORDER BY x LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
SELECT x FROM t1 WHERE id > (SELECT MAX(id) - 1000 FROM t1) ORDER BY x LIMIT 1;
x
0
drop table t1;
SET optimizer_switch= @@global.optimizer_switch; SET optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size; set @@tmp_table_size= @@global.tmp_table_size;
...@@ -331,7 +331,7 @@ SELECT SUM( c ) ...@@ -331,7 +331,7 @@ SELECT SUM( c )
FROM t2 FROM t2
WHERE (SELECT DISTINCT b FROM t3) > 0); WHERE (SELECT DISTINCT b FROM t3) > 0);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using where; Using index 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
3 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using temporary 3 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using temporary
SELECT * SELECT *
......
...@@ -436,7 +436,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -436,7 +436,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1)) Note 1003 select 1 AS `1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment, `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
...@@ -565,10 +565,10 @@ Warnings: ...@@ -565,10 +565,10 @@ Warnings:
Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1') Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'); EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')))) Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((1 = '1'))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -1378,7 +1378,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal ...@@ -1378,7 +1378,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000); insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1); explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where 1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`)) Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
...@@ -6913,7 +6913,7 @@ INSERT INTO t2 VALUES (1),(2); ...@@ -6913,7 +6913,7 @@ INSERT INTO t2 VALUES (1),(2);
EXPLAIN EXPLAIN
SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1));
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 3 SUBQUERY t1 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1));
......
...@@ -432,7 +432,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -432,7 +432,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1)) Note 1003 select 1 AS `1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment, `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
...@@ -561,10 +561,10 @@ Warnings: ...@@ -561,10 +561,10 @@ Warnings:
Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1') Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'); EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')))) Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((1 = '1'))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -1374,7 +1374,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal ...@@ -1374,7 +1374,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000); insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1); explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where 1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`)) Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
......
...@@ -435,7 +435,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -435,7 +435,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1)) Note 1003 select 1 AS `1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment, `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
...@@ -564,10 +564,10 @@ Warnings: ...@@ -564,10 +564,10 @@ Warnings:
Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1') Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'); EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')))) Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((1 = '1'))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -1377,7 +1377,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal ...@@ -1377,7 +1377,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000); insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1); explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where 1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`)) Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
......
...@@ -432,7 +432,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -432,7 +432,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1)) Note 1003 select 1 AS `1` from `test`.`t1` where 1
drop table t1; drop table t1;
CREATE TABLE `t1` ( CREATE TABLE `t1` (
`numeropost` mediumint(8) unsigned NOT NULL auto_increment, `numeropost` mediumint(8) unsigned NOT NULL auto_increment,
...@@ -561,10 +561,10 @@ Warnings: ...@@ -561,10 +561,10 @@ Warnings:
Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1') Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'); EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index 1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')))) Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((1 = '1'))
drop table t1; drop table t1;
CREATE TABLE t1 (a int(1)); CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
...@@ -1374,7 +1374,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal ...@@ -1374,7 +1374,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000); insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1); explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where 1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings: Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`)) Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
......
...@@ -1865,5 +1865,18 @@ ORDER BY alias1.b; ...@@ -1865,5 +1865,18 @@ ORDER BY alias1.b;
drop table t1, t2, t3; drop table t1, t2, t3;
--echo #
--echo # MDEV-4144 simple subquery causes full scan instead of range scan
--echo #
CREATE TABLE t1 (id int not null auto_increment, x int not null, primary key(id));
INSERT INTO t1 (x) VALUES (0),(0),(0);
EXPLAIN
SELECT x FROM t1 WHERE id > (SELECT MAX(id) - 1000 FROM t1) ORDER BY x LIMIT 1;
SELECT x FROM t1 WHERE id > (SELECT MAX(id) - 1000 FROM t1) ORDER BY x LIMIT 1;
drop table t1;
SET optimizer_switch= @@global.optimizer_switch; SET optimizer_switch= @@global.optimizer_switch;
set @@tmp_table_size= @@global.tmp_table_size; set @@tmp_table_size= @@global.tmp_table_size;
...@@ -547,8 +547,19 @@ bool Item_subselect::is_expensive() ...@@ -547,8 +547,19 @@ bool Item_subselect::is_expensive()
if (!cur_join) if (!cur_join)
continue; continue;
/* If a subquery is not optimized we cannot estimate its cost. */ /*
if (!cur_join->join_tab) Subqueries whose result is known after optimization are not expensive.
Such subqueries have all tables optimized away, thus have no join plan.
*/
if (cur_join->optimized &&
(cur_join->zero_result_cause || !cur_join->tables_list))
return false;
/*
If a subquery is not optimized we cannot estimate its cost. A subquery is
considered optimized if it has a join plan.
*/
if (!(cur_join->optimized && cur_join->join_tab))
return true; return true;
if (sl->first_inner_unit()) if (sl->first_inner_unit())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment