Bug #3341 | Not Optimized Min() | ||
---|---|---|---|
Submitted: | 30 Mar 2004 21:47 | Modified: | 10 May 2004 10:46 |
Reporter: | Sergei Kulakov (Candidate Quality Contributor) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server | Severity: | S3 (Non-critical) |
Version: | 3.23.58; 4.0.18 | OS: | FreeBSD (Free BSD, Windows) |
Assigned to: | Sergei Golubchik | CPU Architecture: | Any |
[30 Mar 2004 21:47]
Sergei Kulakov
[4 Apr 2004 14:50]
MySQL Verification Team
Sorry I wasn't able for to download the file: http://www.rlsnet.ru/Month.zip. I got message that the URL doesn't exist.
[4 Apr 2004 22:49]
Sergei Kulakov
Unfortunately, I typed a comma after the URL and it was automatically converted into a link having the comma as the last character. So, you requested a file named "Month.zip," which obviuosly doesn't exist. The right URL is http://www.rlsnet.ru/Month.zip (to prevent any possible errors, I put it on a separate line). The funny thing is that the link in your answer is correct, too 'cause it has a point after it. Click it and you'll get the file :)
[6 May 2004 2:03]
Timothy Smith
I was able to repeat this on recent 4.0.19 code. Thanks for your excellent bug report. After downloading his table, I did "REPAIR TABLE Month USE_FRM" to restore an index file. I did each query a few times, to verify his results. Then I did FLUSH STATUS, and ran the min() query. Then another FLUSH STATUS, and I ran the LIMIT query. Here is a diff of the two: tim@sand:m/40/m$ diff min-status.txt limit-status.txt 6,7c6,7 < | Bytes_received | 70 | < | Bytes_sent | 58 | --- > | Bytes_received | 88 | > | Bytes_sent | 63 | 87c87 < | Handler_read_next | 9000 | --- > | Handler_read_next | 0 | 95c95 < | Key_read_requests | 291 | --- > | Key_read_requests | 6 | 106c106 < | Questions | 67 | --- > | Questions | 70 | 135c135 < | Uptime | 2231 | --- > | Uptime | 2300 | It is clear from the Handler_read_next that the min() query is not optimal.
[6 May 2004 22:17]
Sergei Golubchik
Thank you for your bug report. This issue has already been fixed in the latest released version of that product, which you can download at http://www.mysql.com/downloads/ Additional info: Frankly speaking, I wasn't able to repeat the difference between the query with ORDER BY ... LIMIT 1 and without, but I agree MIN() handling is not perfect in 3.23 and 4.0 - it does scan the index. Still, it's not a bug but a missing feature - missing optimization. It was implemented in 4.1 already - your query (w/o order by ... limit 1) is executed in 4.1 by exactly one key lookup - no scan at all.
[10 May 2004 9:12]
Sergei Kulakov
Thanks for the answers. I agree it's kind of a missing feature. But I believe any SQL driver should be able to use indices whenever possible, especially in trivial cases like this. Now and then I get queries for which MySQL doesn't use indices either, especially with backward scanning (it was reported). I mean this kind of missing feature is more important than say adding a function because it influences speed a lot, which I heard is of main priorities. MySQL also does not allow one get a previous value for an index (using HANDLE it is now possible, but I mean SELECT), only the next one. Yes, I can see the difference in using index in newer MySQL version - I got 4.0.1 and 4.0.18 at home and I had a query for which the first didn't use index while the second did (the reference was "const, const, tbl.fld" ). ---------- REPAIR TABLE Month USE_FRM - why?! - I usually use just RESTORE TABLE ... ---------- I wasn't able to repeat the difference - where - in EXPLAIN or in execution time? If the second, the table is too small. If the first then maybe it was a newer version.
[10 May 2004 10:46]
Sergei Golubchik
There's no big difference between REPAIR TABLE Month USE_FRM and RESTORE TABLE in this case. So, both ways are correct :) As for "previous value for an index" - MySQL can do it at least since ISAM (3.22.x) times. It is used for MAX/MIN optimization and (in 4.0) for optimizing ODER BY ... DESC. Of course, I agree that MySQL "should be able to use indices whenever possible" - that's why this optimization is *already* implemented in 4.1 (not "will be" - it's done!). But it cannot be added to the stable branch 4.0, of course, as 4.0 is called "stable" exactly because we do not add new features into it.