Bug #43219 delete does not use index when using OR in where clause
| Submitted: | 26 Feb 2009 9:49 | Modified: | 26 Feb 2009 11:38 |
|---|---|---|---|
| Reporter: | Tilo Prütz | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
| Version: | 5.0.70, 4.1, 5.0, 5.1, 6.0 bzr | OS: | Linux (Gentoo) |
| Assigned to: | CPU Architecture: | Any |
[26 Feb 2009 9:49]
Tilo Prütz
[26 Feb 2009 9:57]
Sveta Smirnova
Thank you for the report. Please provide output of SHOW STATUS LIKE '%handler%'; before and after running DELETE statement.
[26 Feb 2009 10:58]
Tilo Prütz
Hi, here's the requested output. First for DELETE which affects zero rows. mysql> SHOW STATUS LIKE '%handler%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_commit | 0 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_prepare | 0 | | Handler_read_first | 0 | | Handler_read_key | 0 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 48 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 60 | +----------------------------+-------+ 15 rows in set (0.00 sec) mysql> delete from test where (type=5) or (id=123456 and type=3); Query OK, 0 rows affected (12.13 sec) mysql> SHOW STATUS LIKE '%handler%'; +----------------------------+---------+ | Variable_name | Value | +----------------------------+---------+ | Handler_commit | 1 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_prepare | 0 | | Handler_read_first | 1 | | Handler_read_key | 2 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 4500065 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 75 | +----------------------------+---------+ 15 rows in set (0.00 sec) Now for DELETE which affects 500000 rows. mysql> SHOW STATUS LIKE '%handler%'; +----------------------------+-------+ | Variable_name | Value | +----------------------------+-------+ | Handler_commit | 0 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_prepare | 0 | | Handler_read_first | 0 | | Handler_read_key | 0 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 48 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 60 | +----------------------------+-------+ 15 rows in set (0.00 sec) mysql> delete from test where (type=4) or (id=123456 and type=3); Query OK, 500000 rows affected (1 min 6.46 sec) mysql> SHOW STATUS LIKE '%handler%'; +----------------------------+---------+ | Variable_name | Value | +----------------------------+---------+ | Handler_commit | 1 | | Handler_delete | 0 | | Handler_discover | 0 | | Handler_prepare | 0 | | Handler_read_first | 1 | | Handler_read_key | 2 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 4500065 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 75 | +----------------------------+---------+ 15 rows in set (0.00 sec)
[26 Feb 2009 11:38]
Sveta Smirnova
Thank you for the report. Verified as described. Test case for the test suite: CREATE TABLE test (id int not null primary key, type1 int not null); CREATE INDEX idx ON test (id, type1); insert into test values(1,1), (2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0); explain select * from test WHERE (type1=5) OR (type1=3 AND id=3); SHOW STATUS LIKE '%handler%'; select * from test WHERE (type1=5) OR (type1=3 AND id=3); SHOW STATUS LIKE '%handler%'; delete from test WHERE (type1=5) OR (type1=3 AND id=3); SHOW STATUS LIKE '%handler%';
[16 Mar 2009 11:22]
Sergey Petrunya
Omer, At the first glance these two bugs to not seem to be duplicates.
[23 Dec 2020 7:44]
Shane Bester
Is this bug really valid? I thought it has to do a table or index scan to check condition "b=5" I tried a bigger testcase on newer versions so it seems expected output to me, or do I miss something? Probably reporter needs a better index on (type,id) instead of (id,type) ?? -- -------- drop table if exists t; create table t (a int not null primary key, b int not null)engine=innodb; create index ax on t(a, b); set @a:=0; replace into t select @a:=@a+1,floor(rand()*10); replace into t select @a:=@a+1,floor(rand()*10); replace into t select @a:=@a+1,floor(rand()*10); replace into t select @a:=@a+1,floor(rand()*10); replace into t select @a:=@a+1,floor(rand()*10); replace into t select @a:=@a+1,floor(rand()*10); replace into t select @a:=@a+1,floor(rand()*10) from t a,t b,t c,t d,t e,t f,t g,t h limit 500000; select count(*) from t; analyze table t; explain select count(*) from t where b=5 or (b=3 and a=123456); explain delete from t where b=5 or (b=3 and a=123456); flush status; select count(*) from t where b=5 or (b=3 and a=123456); show status like '%handler%'; set session optimizer_trace = "enabled=on"; flush status; delete from t where b=5 or (b=3 and a=123456); show status like '%handler%'; select * from information_schema.optimizer_trace\G set session optimizer_trace = "enabled=on"; select version(); -- -----------
[23 Dec 2020 7:46]
Shane Bester
In Sveta's testcase the index shouldn't be: CREATE INDEX idx ON test (id, type1); it should be: CREATE INDEX idx ON test (type1, id);
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.040 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.