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.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.045 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.