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).
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.043 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.