| Bug #45145 | Index is not used when an IN expression contains a single-value subquery | ||
|---|---|---|---|
| Submitted: | 27 May 2009 22:17 | Modified: | 5 Jun 2009 21:27 |
| Reporter: | Alex Bolenok | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S5 (Performance) |
| Version: | 5.2 | OS: | Windows |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | IN, INDEX, range, subquery | ||
[4 Jun 2009 6:21]
Valeriy Kravchuk
Thank you for the problem report. Please, specify the exact version, x.y.z, you had used. I doubt it is 5.2.
[5 Jun 2009 19:32]
Alex Bolenok
SELECT VERSION(); '5.2.0-falcon-alpha-community-nt-log'
[5 Jun 2009 19:56]
Valeriy Kravchuk
This is a very old version. 5.2 became 6.0 later, so, please, check with the newer version, 6.0.11, and inform about the results.
[5 Jun 2009 21:27]
Alex Bolenok
Right, seems to be corrected in 6.0

Description: When an IN expression on an indexed column contains a single-value subquery, the optimizer is not able to use the index. How to repeat: SELECT VERSION(); CREATE TABLE t_selector (id INT NOT NULL PRIMARY KEY, value VARCHAR(50) NOT NULL) ENGINE=InnoDB; INSERT INTO t_selector VALUES (1, 'Value 1'), (2, 'Value 2'), (3, 'Value 3'), (4, 'Value 4'); EXPLAIN SELECT * FROM t_selector so FORCE INDEX (PRIMARY) WHERE so.id = 1 OR so.id = (SELECT si.id FROM t_selector si WHERE si.id = 2); 1, 'PRIMARY', 'so', 'range', 'PRIMARY', 'PRIMARY', '4', '', 2, 'Using where' 2, 'SUBQUERY', 'si', 'const', 'PRIMARY', 'PRIMARY', '4', '', 1, 'Using index' EXPLAIN SELECT * FROM t_selector so FORCE INDEX (PRIMARY) WHERE so.id IN (1, (SELECT si.id FROM t_selector si WHERE si.id = 2)); 1, 'PRIMARY', 'so', 'ALL', '', '', '', '', 4, 'Using where' 2, 'SUBQUERY', 'si', 'const', 'PRIMARY', 'PRIMARY', '4', 'const', 1, 'Using index' I expected the second query to use the PRIMARY KEY, just as the first query does. However, the index is not used even despite FORCE INDEX (PRIMARY) explicitly provided. Suggested fix: Fix the optimizer algorithm so that it uses RANGE access for such a query.