Bug #79340 UNION ALL ... LIMIT 1 evaluates too many rows in 5.5/6 and twice more in 5.7
Submitted: 19 Nov 2015 14:40 Modified: 16 Aug 2019 19:19
Reporter: Guilhem Bichot Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:5.7.9 OS:Any
Assigned to: CPU Architecture:Any

[19 Nov 2015 14:40] Guilhem Bichot
Description:
Table with 1024 rows.

select * from t1 limit 1
properly gives:
Handler_read_rnd_next	1

But

select * from t1 union all select * from t1 limit 1
gives
Handler_read_rnd_next	1027
in 5.5 and 5.6,
Handler_read_rnd_next	2050
in 5.7.

So 5.7 is twice worse than 5.5/6. But even 5.5/6 are inefficient: as soon as the LIMIT has been satisfied (i.e. one row has been effectively sent to the client), there is no reason to continue reading rows from t1 (to just discard them immediately!): statement should stop executing (if there were ORDER BY it would be different). Just like the non-UNION version.

How to repeat:
create table t1(a int);
insert into t1 values(1);
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
insert into t1 select a+1 from t1;
select count(*) from t1;
flush status; select * from t1 limit 1; show status like "handler_read%";
flush status; select * from t1 union all select * from t1 limit 1; show status like "handler_read%";
drop table t1;
[30 Oct 2018 9:16] Guilhem Bichot
see also https://bugs.mysql.com/bug.php?id=92994
[16 Aug 2019 19:19] Jon Stephens
Documented fix in the MySQL 8.0.18 changelog as follows:

    Queries using UNION ALL ... LIMIT 1 evaluated an excessive
    number of rows as shown by Handler_read, Handler_read_key, and
    Handler_read_next.

See also BUG#79040, BUG#92994.

Closed.