Bug #75435 | MAX() causes a full table scan when used in a sub-query | ||
---|---|---|---|
Submitted: | 7 Jan 2015 14:59 | Modified: | 12 Jan 2015 18:42 |
Reporter: | Van Stokes | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
Version: | 5.6.21 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[7 Jan 2015 14:59]
Van Stokes
[12 Jan 2015 15:06]
MySQL Verification Team
This is expected behavior. If you explain both EXPLAINs you shall see that query node as a nested query and standalone query have 100 % identical execution plan. Your problem is that highest level query gets a full table scan. That is actually a cause of the design problem that was introduced when nested queries were developed, which affects a large number of queries that use nested queries. There are plans to solve this problem, but scheduling is yet unknown. The only thing that you can try is to have an index on the column `Bol` and to avoid nested query by using prepared statements or stored function that will create a string with values in brackets returned by your inner query as standalone one.
[12 Jan 2015 18:16]
Van Stokes
Thank you for your reply. I am intrigued by this: "..stored function that will create a string with values in brackets.." Would you please provide an example SELECT statement showing how to use string values in brackets?
[12 Jan 2015 18:42]
Van Stokes
And to anyone else who finds this, I re-wrote the query like this and it vastly improved performance: SELECT fcl_bl.BolId, fcl_bl.file_number FROM ( SELECT MAX( fcl_bl.Bol ) AS 'bol' FROM fcl_bl WHERE fcl_bl.sail_date BETWEEN DATE_FORMAT( '20141201', '%Y-%m-%d 00:00:00' ) AND DATE_FORMAT( '20141231', '%Y-%m-%d 23:59:59' ) AND fcl_bl.filetype != 'I' AND ( fcl_bl.void IS NULL OR fcl_bl.void = 'N' ) GROUP BY fcl_bl.file_no ) t, fcl_bl WHERE fcl_bl.Bol = t.bol ;
[14 Jan 2015 15:54]
MySQL Verification Team
SELECT ...... WHERE Bol IN (1,2,3,4,5);
[14 Jan 2015 15:56]
MySQL Verification Team
Actually, you would have two strings, one with "SELECT .... IN " and one with "(1,2,3,4,5)", you would concatenate those two strings and execute the statement.