Bug #76398 | MySQL doing full scan depending on limit value with ORDER BY query | ||
---|---|---|---|
Submitted: | 19 Mar 2015 20:27 | Modified: | 11 Apr 2020 2:20 |
Reporter: | Christophe Fondacci | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
Version: | 5.6.23, 5.6.25, 5.5.44 | OS: | Any (CentOS, Mac OS X) |
Assigned to: | CPU Architecture: | Any | |
Tags: | filesort, full scan, limit, order |
[19 Mar 2015 20:27]
Christophe Fondacci
[20 Mar 2015 8:32]
MySQL Verification Team
Thank you for the report. I could not repeat with the dummy data at my end. Could you please provide repeatable data(sql dump - you can mark it as private note after uploading)? Thanks, Umesh
[24 Mar 2015 12:21]
MySQL Verification Team
Thank you for the test case. I see similar behavior with 5.5.44, 5.6.25. It could be by design/known issue but I could not locate a bug which confirms whether plan changes depending on constant in LIMIT. // 5.6.25 mysql> show variables like '%version%'; +-------------------------+---------------------------------------------------------+ | Variable_name | Value | +-------------------------+---------------------------------------------------------+ | innodb_version | 5.6.25 | | protocol_version | 10 | | slave_type_conversions | | | version | 5.6.25-enterprise-commercial-advanced | | version_comment | MySQL Enterprise Server - Advanced Edition (Commercial) | | version_compile_machine | x86_64 | | version_compile_os | linux-glibc2.5 | +-------------------------+---------------------------------------------------------+ 7 rows in set (0.00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 20; +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ | 1 | SIMPLE | ACTIVITIES | index | NULL | ACTI_DATE_I | 4 | NULL | 20 | NULL | +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ 1 row in set (0.00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 150; +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ | 1 | SIMPLE | ACTIVITIES | ALL | NULL | NULL | NULL | NULL | 10914 | Using filesort | +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ 1 row in set (0.00 sec) mysql> // 5.5.44 mysql> show variables like '%version%'; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | innodb_version | 5.5.44 | | protocol_version | 10 | | slave_type_conversions | | | version | 5.5.44 | | version_comment | MySQL Community Server (GPL) | | version_compile_machine | x86_64 | | version_compile_os | linux2.6 | +-------------------------+------------------------------+ 7 rows in set (0.00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 20; +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ | 1 | SIMPLE | ACTIVITIES | index | NULL | ACTI_DATE_I | 4 | NULL | 20 | | +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ 1 row in set (0.00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 150; +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ | 1 | SIMPLE | ACTIVITIES | ALL | NULL | NULL | NULL | NULL | 10638 | Using filesort | +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ 1 row in set (0.00 sec) mysql> // 5.1.73 mysql> show variables like '%version%'; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | protocol_version | 10 | | version | 5.1.73 | | version_comment | MySQL Community Server (GPL) | | version_compile_machine | x86_64 | | version_compile_os | unknown-linux-gnu | +-------------------------+------------------------------+ 5 rows in set (0.00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 20; +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ | 1 | SIMPLE | ACTIVITIES | index | NULL | ACTI_DATE_I | 4 | NULL | 20 | | +----+-------------+------------+-------+---------------+-------------+---------+------+------+-------+ 1 row in set (0.00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 150; +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ | 1 | SIMPLE | ACTIVITIES | ALL | NULL | NULL | NULL | NULL | 11376 | Using filesort | +----+-------------+------------+------+---------------+------+---------+------+-------+----------------+ 1 row in set (0.00 sec) mysql>
[14 Nov 2016 9:41]
Øystein Grøvlen
Posted by developer: It seems the switch-over point is different when limit optimization is considered compared to when switch happen for range optimization. Tested 5.7.16: Switch-over for limit query is same as report in the bug report (97): mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 96; +----+-------------+------------+------------+-------+---------------+-------------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+-------+---------------+-------------+---------+------+------+----------+-------+ | 1 | SIMPLE | ACTIVITIES | NULL | index | NULL | ACTI_DATE_I | 4 | NULL | 96 | 100.00 | NULL | +----+-------------+------------+------------+-------+---------------+-------------+---------+------+------+----------+-------+ 1 row in set, 1 warning (0,00 sec) mysql> explain select * from ACTIVITIES order by ACTIVITY_DATE desc limit 97; +----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+----------------+ | 1 | SIMPLE | ACTIVITIES | NULL | ALL | NULL | NULL | NULL | NULL | 10914 | 100.00 | Using filesort | +----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+----------------+ 1 row in set, 1 warning (0,00 sec) For range optimization the switch-over is around 1900: mysql> explain select * from ACTIVITIES WHERE activity_date > '2014-10-02'; +----+-------------+------------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | ACTIVITIES | NULL | range | ACTI_DATE_I | ACTI_DATE_I | 4 | NULL | 1897 | 100.00 | Using index condition | +----+-------------+------------+------------+-------+---------------+-------------+---------+------+------+----------+-----------------------+ 1 row in set, 1 warning (0,00 sec) mysql> explain select * from ACTIVITIES WHERE activity_date > '2014-10-01'; +----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+-------------+ | 1 | SIMPLE | ACTIVITIES | NULL | ALL | ACTI_DATE_I | NULL | NULL | NULL | 10914 | 17.44 | Using where | +----+-------------+------------+------------+------+---------------+------+---------+------+-------+----------+-------------+ 1 row in set, 1 warning (0,00 sec) mysql> select count(*) from ACTIVITIES WHERE activity_date > '2014-10-02'; +----------+ | count(*) | +----------+ | 1897 | +----------+ 1 row in set (0,00 sec)
[11 Apr 2020 2:21]
Jon Stephens
Disregard previous comment from me, was looking at wrong WL.