| Bug #43187 | SELECT ... WHERE (col1, col2) IN ((const, const)) is optimized, non-SELECT not | ||
|---|---|---|---|
| Submitted: | 25 Feb 2009 13:45 | Modified: | 30 Jul 2012 17:42 |
| Reporter: | Axel Schwenke | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S5 (Performance) |
| Version: | 5.0, 5.1, 5.6 | OS: | Linux |
| Assigned to: | CPU Architecture: | Any | |
[25 Feb 2009 13:45]
Axel Schwenke
[25 Feb 2009 14:03]
Axel Schwenke
This is on 6.0 and proves a table scan is used: mysql>flush status; mysql>select * from t1 where (c1, c2) IN ((4, 12345)); +----+-------+ | c1 | c2 | +----+-------+ | 4 | 12345 | +----+-------+ 1 row in set (0,00 sec) mysql>show status like 'handler_%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_read_key | 1 | | Handler_read_rnd_next | 0 | +----------------------------+-------+ mysql>flush status; mysql>delete from t1 where (c1, c2) IN ((4, 12345)); Query OK, 1 row affected (3,72 sec) mysql>show status like 'handler_%'; +----------------------------+----------+ | Variable_name | Value | +----------------------------+----------+ | Handler_delete | 1 | | Handler_read_key | 0 | | Handler_read_rnd_next | 10485761 | +----------------------------+----------+
[3 Mar 2009 18:18]
Valeriy Kravchuk
Bug #43334 is marked as a duplicate of this one.
[14 Oct 2011 6:51]
Valeriy Kravchuk
Bug #62731 was marked as a duplicate of this one.
[27 Feb 2012 9:20]
Axel Schwenke
In MySQL-5.6 we can now use EXPLAIN to see the fail. Create and fill tables like before. Then run this SQL:
-- fetch an existing number (auto_inc not consecutive any more)
select @n:=c1 from t2 where c1>12345 limit 1;
-- explain and execution of select
explain select * from t1 where (c1, c2) IN ((4, @n))\G
select * from t1 where (c1, c2) IN ((4, @n));
-- explain and execution of delete
explain delete from t1 where (c1, c2) IN ((4, @n))\G
delete from t1 where (c1, c2) IN ((4, @n));
Result:
mysql>select @n:=c1 from t2 where c1>12345 limit 1;
+--------+
| @n:=c1 |
+--------+
| 16371 |
+--------+
1 row in set (0,00 sec)
mysql>explain select * from t1 where (c1, c2) IN ((4, @n))\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 8
ref: const,const
rows: 1
Extra: Using index
1 row in set (0,01 sec)
mysql>select * from t1 where (c1, c2) IN ((4, @n));
+----+-------+
| c1 | c2 |
+----+-------+
| 4 | 16371 |
+----+-------+
1 row in set (0,01 sec)
mysql>explain delete from t1 where (c1, c2) IN ((4, @n))\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 10486405
Extra: Using where
1 row in set (0,00 sec)
mysql>delete from t1 where (c1, c2) IN ((4, @n));
Query OK, 1 row affected (11,81 sec)
[30 Jul 2012 17:42]
Paul DuBois
Noted in 5.6.6 changelog. Queries that used WHERE (col1, col2) IN ((const, const)) were optimized for SELECT, but not for DELETE or UPDATE.
[27 Sep 2012 16:59]
Jon Stephens
Also fixed in trunk (currently tagged 5.7.0).
