Bug #30686 | inappropriate LIMIT behavior on partitioned single-table query sorted by PK | ||
---|---|---|---|
Submitted: | 29 Aug 2007 9:37 | Modified: | 3 Jun 2009 13:14 |
Reporter: | Theodore Dubro | Email Updates: | |
Status: | No Feedback | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.1.20-beta-community-nt-debug, 5.1.30 | OS: | Windows ((via TCP/IP)) |
Assigned to: | CPU Architecture: | Any | |
Tags: | limit, syntax, temp tables |
[29 Aug 2007 9:37]
Theodore Dubro
[29 Aug 2007 10:36]
Theodore Dubro
That's a MyISAM table. (d'oh)
[29 Aug 2007 11:13]
Hartmut Holzgraefe
Could you provide EXPLAIN output for both queries? You may also consider FORCE INDEX instead of LIMIT here ...
[29 Aug 2007 12:52]
Theodore Dubro
#1) without LIMIT (or LIMIT > x): Simple, type=ALL, key=NULL, keylen=NULL, rows=12130921, Extra=Using filesort #2) LIMIT = x: Simple, type=index, key=PRIMARY, rows=12130921, Extra=[blank] FORCE INDEX (PRIMARY) solved my immediate problem, so I guess this goes under "Optimizer". Thanks for the quick response.
[28 Oct 2007 14:21]
Valeriy Kravchuk
Please, try to repeat with a newer version, 5.1.22, and inform about the results.
[4 Nov 2007 6:21]
Theodore Dubro
Sorry, had to fix references to the deprecated mysqld-nt bin. Same table-scan behavior in .22 without FORCE INDEX (all rows, "Using filesort"), but LIMIT n does the same thing now instead of grabbing the primary key, so it's consistent at least.
[14 Feb 2008 4:31]
Valeriy Kravchuk
Please, check with a newer version, 5.1.23-rc. See also bug #28404 that can be related.
[15 Mar 2008 0:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".
[19 Mar 2008 17:08]
Susanne Ebrecht
We still need to know if you get this issue by using our newest version MySQL 5.1.23.
[19 Apr 2008 23:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".
[20 Apr 2008 3:08]
Theodore Dubro
Sorry for the delay. I don't think the optimizer's making the right call in .23-rc, but the resolution to #28404 might explain why ("ORDER BY is used with LIMIT N and the cost of N random accesses is less than the cost of filesort"); now instead of table scanning LIMIT anything-but-N the optimizer makes an (arbitrary?) judgment call, but using the index should always cost "less than the cost of filesort" in this scenario (see the last two queries, 1 hour vs. 1 millisecond): explain select id, url from p_pix FORCE INDEX(primary) order by url desc limit 16765752 -> key PRIMARY, Extra=<blank>, rows 16765752 explain select id, url from p_pix FORCE INDEX(primary) order by url desc -> key PRIMARY, Extra=<blank>, rows 16765752 explain select id, url from p_pix order by url desc limit 16765752 -> key NULL, Extra=Using Filesort, rows 16765752 explain select id, url from p_pix order by url desc -> key NULL, Extra=Using Filesort, rows 16765752 explain select id, url from p_pix order by url desc limit 388000 (or more) -> key NULL, Extra=Using Filesort, rows 16765752 explain select id, url from p_pix order by url desc limit 387000 -> key PRIMARY, Extra=<blank>, rows 387000
[4 May 2008 14:56]
Valeriy Kravchuk
Please, try to repeat with a newer version, 5.1.24, and inform about the results.
[27 May 2008 16:13]
Theodore Dubro
same behavior in 5.1.24, "Using Filesort" until FORCE INDEX(PRIMARY) is specified.
[4 Jul 2008 20:00]
Valeriy Kravchuk
Please, check with a newer version, 5.1.25-rc. In case of the same problem, please, send the results of SHOW CREATE TABLE for the table used.
[4 Aug 2008 23:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".
[9 Dec 2008 22:17]
Theodore Dubro
Same thing in 5.1.30 (and myisam in 6.0.8 alpha); what's interesting is swapping the primary key and unique index ("secondary_index_column" in the example) has no effect on the optimizer's choice, and I still need to FORCE INDEX(Index_n) instead of FORCE INDEX(PRIMARY) to see timely results. What I should have mentioned is the former primary key (now unique index) is either a CHAR or VARCHAR in the 100 byte range, which might have something to do with the ORDER BY wanting to create a temp table instead of grabbing the right key as the FORCE INDEX accomplishes. Output: the good: explain SELECT id, url, @num := @num + 1 gid from p_pix FORCE INDEX(Index_66), (SELECT @num :=0) d order by url desc id#1: PRIMARY <derived2> system NULL NULL NULL NULL 1 Extra=[blank] id#1: PRIMARY p_pix index NULL Index_66 125 NULL 18940234 Extra=Using where id#2: DERIVED NULL NULL NULL NULL NULL NULL NULL Extra=No tables used the bad: explain SELECT id, url, @num := @num + 1 gid from p_pix, (SELECT @num :=0) d order by url desc id#1: PRIMARY <derived2> system NULL NULL NULL NULL 1 Extra=Using filesort <-- id#1: PRIMARY p_pix ALL<-- NULL<-- NULL NULL <-- NULL 18940234 Extra=Using where id#2: DERIVED NULL NULL NULL NULL NULL NULL NULL Extra=No tables used (note: with a WHERE clause, the second explain row is still key=NULL, but possible_keys becomes one secondary index covered by the WHERE, but it still goes with "Using filesort" anyway)
[11 Dec 2008 15:33]
Sveta Smirnova
Thank you for the feedback. Please send output of SHOW CREATE TABLE for table used.
[11 Dec 2008 21:33]
Theodore Dubro
DROP TABLE IF EXISTS `test`.`p_pix`; CREATE TABLE `test`.`p_pix` ( `url` char(125) NOT NULL DEFAULT '0', `timestamp` int(10) unsigned NOT NULL DEFAULT '0', `status` char(1) NOT NULL DEFAULT '?', `type` bit(1) NOT NULL DEFAULT '\0', `originid` mediumint(8) unsigned NOT NULL DEFAULT '0', `checksum` char(22) DEFAULT NULL, `size` mediumint(8) unsigned NOT NULL DEFAULT '0', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `Index_66` (`url`) USING BTREE, KEY `Index_72` (`originid`), KEY `Index_75` (`checksum`,`size`), KEY `Index_8` (`timestamp`,`status`) USING BTREE, KEY `Index_74` (`status`,`timestamp`) USING BTREE ) ENGINE=MyISAM AUTO_INCREMENT=18952854 DEFAULT CHARSET=latin1 PACK_KEYS=1 ROW_FORMAT=FIXED; (note: same behavior with dynamic or fixed rows (and CHAR or VARCHAR); partitioning irrelevant (besides the inappropriately titled bug report), and it doesn't seem to matter whether `id` (or `url`) is a primary, unique or non-unique index)
[3 May 2009 13:14]
Valeriy Kravchuk
Please, specify what exactly is considered a bug here. I can confirm your findings with the recent (non-partitioned) p_pix table: for ORDER BY without LIMIT index on url column is NOT used: mysql> select version(); +--------------+ | version() | +--------------+ | 5.1.34-debug | +--------------+ 1 row in set (0.00 sec) mysql> CREATE TABLE `test`.`p_pix` ( -> `url` char(125) NOT NULL DEFAULT '0', -> `timestamp` int(10) unsigned NOT NULL DEFAULT '0', -> `status` char(1) NOT NULL DEFAULT '?', -> `type` bit(1) NOT NULL DEFAULT '\0', -> `originid` mediumint(8) unsigned NOT NULL DEFAULT '0', -> `checksum` char(22) DEFAULT NULL, -> `size` mediumint(8) unsigned NOT NULL DEFAULT '0', -> `id` int(10) unsigned NOT NULL AUTO_INCREMENT, -> PRIMARY KEY (`id`) USING BTREE, -> UNIQUE KEY `Index_66` (`url`) USING BTREE, -> KEY `Index_72` (`originid`), -> KEY `Index_75` (`checksum`,`size`), -> KEY `Index_8` (`timestamp`,`status`) USING BTREE, -> KEY `Index_74` (`status`,`timestamp`) USING BTREE -> ) ENGINE=MyISAM AUTO_INCREMENT=18952854 DEFAULT CHARSET=latin1 PACK_KEYS=1 -> ROW_FORMAT=FIXED; Query OK, 0 rows affected (0.06 sec) mysql> mysql> insert into p_pix(url) values ('http://mysql.com';); Query OK, 1 row affected (0.19 sec) mysql> insert into p_pix(url) values ('http://oracle.com';); Query OK, 1 row affected (0.00 sec) mysql> insert into p_pix(url) select (concat('http://';, concat(rand()*1000000,'oracle.com'))) from p_pix; Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into p_pix(url) select (concat('http://';, concat(rand()*1000000,'oracle.com'))) from p_pix; Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0 ... mysql> insert into p_pix(url) select (concat('http://';, concat(rand()*1000000,'oracle.com'))) from p_pix; ERROR 1062 (23000): Duplicate entry 'http://855265.308968039oracle.com'; for key 'Index_66' mysql> select count(*) from p_pix; +----------+ | count(*) | +----------+ | 3819 | +----------+ 1 row in set (0.00 sec) mysql> explain SELECT id, url, @num := @num + 1 gid from p_pix, (SELECT @num :=0) d order by url desc\G *************************** 1. row *************************** id: 1 select_type: PRIMARY table: <derived2> type: system possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1 Extra: Using filesort *************************** 2. row *************************** id: 1 select_type: PRIMARY table: p_pix type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 3819 Extra: *************************** 3. row *************************** id: 2 select_type: DERIVED table: NULL type: NULL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL Extra: No tables used 3 rows in set (0.00 sec) Indeed, index can be used: mysql> explain SELECT id, url, @num := @num + 1 gid from p_pix force index(Index_66), (SELECT @num :=0) d order by url desc\G *************************** 1. row *************************** id: 1 select_type: PRIMARY table: <derived2> type: system possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1 Extra: *************************** 2. row *************************** id: 1 select_type: PRIMARY table: p_pix type: index possible_keys: NULL key: Index_66 key_len: 125 ref: NULL rows: 3819 Extra: *************************** 3. row *************************** id: 2 select_type: DERIVED table: NULL type: NULL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL Extra: No tables used 3 rows in set (0.00 sec) Now, we can see the same with simplified query as well: mysql> explain SELECT id, url from p_pix order by url desc\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: p_pix type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 3819 Extra: Using filesort 1 row in set (0.00 sec) But with LIMIT N where N is much less than total number of rows in the table index is used: mysql> explain SELECT id, url from p_pix order by url desc LIMIT 10\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: p_pix type: index possible_keys: NULL key: Index_66 key_len: 125 ref: NULL rows: 10 Extra: 1 row in set (0.00 sec) and, coming back to the original claim, when LIMIT <total_number_of_rows> is used we have the same plan as without LIMIT: mysql> explain SELECT id, url from p_pix order by url desc LIMIT 3819\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: p_pix type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 3819 Extra: Using filesort 1 row in set (0.00 sec) So, what exactly is a bug now?
[3 Jun 2009 23:00]
Bugs System
No feedback was provided for this bug for over a month, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open".