Bug #78993 | Optimizer use index scan instead of range scan by mistake | ||
---|---|---|---|
Submitted: | 28 Oct 2015 3:15 | Modified: | 1 Feb 2016 15:54 |
Reporter: | zhang yingqiang (OCA) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 5.6.16 5.6.26, 5.6.27 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | Optimizer, regression |
[28 Oct 2015 3:15]
zhang yingqiang
[28 Oct 2015 5:01]
MySQL Verification Team
Hello zhang yingqian, Thank you for the report and contribution. Verified as described with 5.6.27 build. Thanks, Umesh
[28 Oct 2015 5:03]
MySQL Verification Team
// only 5.6 seems to use index type // 5.1.77 mysql> explain select id from t1 where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | 1 | SIMPLE | t1 | range | iabc,ic | iabc | 5 | NULL | 3 | Using where; Using index; Using filesort | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ 1 row in set (0.00 sec) mysql> explain select id from t1 force index (iabc) where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | 1 | SIMPLE | t1 | range | iabc | iabc | 5 | NULL | 3 | Using where; Using index; Using filesort | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ 1 row in set (0.00 sec) // 5.5.47 mysql> explain select id from t1 where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | 1 | SIMPLE | t1 | range | iabc,ic | iabc | 5 | NULL | 3 | Using where; Using index; Using filesort | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ 1 row in set (0.00 sec) mysql> explain select id from t1 force index (iabc) where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | 1 | SIMPLE | t1 | range | iabc | iabc | 5 | NULL | 3 | Using where; Using index; Using filesort | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ 1 row in set (0.00 sec)
[28 Oct 2015 5:04]
MySQL Verification Team
// 5.6.27 mysql> explain select id from t1 where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | 1 | SIMPLE | t1 | index | iabc,ic | iabc | 15 | NULL | 32 | Using where; Using index; Using filesort | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ 1 row in set (0.00 sec) mysql> explain select id from t1 force index (iabc) where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ | 1 | SIMPLE | t1 | range | iabc | iabc | 5 | NULL | 3 | Using where; Using index; Using filesort | +----+-------------+-------+-------+---------------+------+---------+------+------+------------------------------------------+ 1 row in set (0.00 sec) // 5.7.9 mysql> explain select id from t1 where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | 1 | SIMPLE | t1 | NULL | range | iabc,ic | iabc | 5 | NULL | 4 | 10.62 | Using where; Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ 1 row in set, 1 warning (0.01 sec) mysql> explain select id from t1 force index (iabc) where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | 1 | SIMPLE | t1 | NULL | range | iabc | iabc | 5 | NULL | 4 | 6.67 | Using where; Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ 1 row in set, 1 warning (0.00 sec) // 5.7.10 mysql> explain select id from t1 where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | 1 | SIMPLE | t1 | NULL | range | iabc,ic | iabc | 5 | NULL | 4 | 10.62 | Using where; Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> explain select id from t1 force index (iabc) where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | 1 | SIMPLE | t1 | NULL | range | iabc | iabc | 5 | NULL | 4 | 6.67 | Using where; Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ 1 row in set, 1 warning (0.00 sec)
[28 Oct 2015 6:06]
zhang yingqiang
This bug result in full index scan, it cost too much CPU and IO !! I also check the test case in 5.7.8, there is no such problem.
[3 Nov 2015 14:06]
qinglin zhang
fix for order by limt cause
Attachment: a.diff (application/octet-stream, text), 1.20 KiB.
[3 Nov 2015 14:16]
qinglin zhang
just part of code, which we may calculate the cost by considering read plan before.
Attachment: a.diff (application/octet-stream, text), 1.25 KiB.
[1 Feb 2016 15:54]
Paul DuBois
Noted in 5.7.6 changelog. For queries that combine ORDER BY with LIMIT, the optimizer may switch to an index that applies to the ORDER BY. In some cases, the decision to switch was based on a heuristic rather than on cost. The optimizer now uniformly makes the decision whether to switch on a cost basis. This should result in better performanance when switching would cause a query to read an entire index or a large part of it to find qualifying rows.
[20 Aug 2017 9:24]
WANG GUANGYOU
// 5.7.10 mysql> explain select id from t1 where a<3 and b in (1, 13) and c>=3 order by c desc limit 2; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ | 1 | SIMPLE | t1 | NULL | range | iabc,ic | iabc | 5 | NULL | 4 | 10.62 | Using where; Using index; Using filesort | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------+ 1 row in set, 1 warning (0.00 sec) this worked in 5.7.10 for it does not trigger LOW_LIMIT branch. Cheers! I check the code, the Heuristic algorithm is moved in order by limit case . We are deeply troubled in this bug at MeiTuanDianPing in MySQL5.6.