简体   繁体   中英

Optimize MYSQL Query having a subquery

/* Guys Can anyone help me how to optimize the below mentioned query. In the subquery , i am calculating the diff between shipping date and creation date (of a product) as time_to_shift . Then in the outer query I want to count orders on the basis of time_to_shift slabs. The below given query works but takes a lot of time . Can anyone tell me how to create indexes on a subquery and use them in the outer query. This also might solve the problem. */

SELECT DATE_FORMAT(b.ship_date,'%Y-%m')  AS MONTH, 
COUNT(*) AS Total_units_shipped, 
ROUND(100*COUNT(CASE WHEN time_to_ship <= 0 THEN time_to_ship END)/COUNT(*),2) AS '0 day',
ROUND(100*COUNT(CASE WHEN time_to_ship =1 THEN time_to_ship END)/COUNT(*),2) AS '1 day',
ROUND(100*COUNT(CASE WHEN time_to_ship> 1  AND time_to_ship<= 2 THEN time_to_ship END)/COUNT(*),2) AS '1-2 days',
ROUND(100*COUNT(CASE WHEN time_to_ship >2 AND time_to_ship <= 4 THEN time_to_ship END)/COUNT(*),2) AS '3-4 days',
ROUND(100*COUNT(CASE WHEN time_to_ship > 4 AND time_to_ship <= 10 THEN time_to_ship END)/COUNT(*),2) AS '5-10 days', 
ROUND(100*COUNT(CASE WHEN time_to_ship > 10 AND time_to_ship <= 20 THEN time_to_ship END)/COUNT(*),2) AS '11-20 days', 
ROUND(100*COUNT(CASE WHEN time_to_ship >20 THEN time_to_ship END)/COUNT(*),2) AS '>20 days' 
FROM(
   SELECT 
   DATE(fsp.sp_date_shipped) AS ship_date,
   CASE WHEN WEEKDAY(DATE(fso.soi_date_created)) = 5 THEN 
    (DATEDIFF(DATE(fsp.sph_date_shipped),DATE(fso.soi_date_created)) -1   ) 
      ELSE
       (DATEDIFF(DATE(fsp.sph_date_shipped),DATE(fso.soi_date_created)) ) 
    END
      AS Time_to_Ship 
    FROM dwh.f_suborders_oms fso 
    JOIN dwh.f_shipping_package fsp ON fso.soi_shipping_package_id=fsp.sp_shipping_package_id
    WHERE    fsp.sp_date_shipped BETWEEN DATE_FORMAT(DATE_SUB(CURDATE(),INTERVAL 1 MONTH ),'%Y%m01000000')
    AND DATE_FORMAT( CURDATE(),'%Y%m01000000')
 )b  
GROUP BY 1
LIMIT 1000000 ;

What's the fsp.sp_date_shipped column type? Looks like the problem is

BETWEEN DATE_FORMAT(DATE_SUB(CURDATE(),INTERVAL 1 MONTH ),'%Y%m01000000')
AND DATE_FORMAT( CURDATE(),'%Y%m01000000'). 

Try to avoid DATE_FORMAT and use dates rathar than formatted output to let index work instead of full scan

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM