記錄一次sql查詢union的優化


1.原來的sql:

 

SELECT  t.city_id as cityId,t.city_name as cityName, t.group_id as groupId, t.supplier_name as supplierName,t.id,t.driver_name as driverName,t.license_plates as licensePlates,t.driver_id as driverId,
    t.driver_phone as driverPhone,
    case WHEN m.`status`=1 THEN m.main_order_no  ELSE '' END mainOrder,
    case WHEN m.`status`=1 THEN m.main_name  ELSE '' END subRouteName,
    case WHEN m.`status`=1 THEN m.main_time  ELSE '' END mainOrderTime
    FROM main_order_inter_city m inner JOIN  driver_info_inter_city t
    on t.driver_id =  m.driver_id
    WHERE 1=1   and m.status=1 and t.status =1
        
        UNION
      SELECT t.city_id as cityId,t.city_name as cityName, t.group_id as groupId, t.supplier_name as supplierName,t.id,t.driver_name as driverName,t.license_plates as licensePlates,t.driver_id as driverId,
    t.driver_phone as driverPhone,
    case WHEN m.`status`=1 THEN '' ELSE '' END mainOrder,
    case WHEN m.`status`=1 THEN ''  ELSE '' END subRouteName,
    case WHEN m.`status`=1 THEN ''  ELSE '' END mainOrderTime
    FROM driver_info_inter_city t left JOIN  main_order_inter_city m  
    on t.driver_id =  m.driver_id
    WHERE  1=1  and t.status =1   

    GROUP BY t.driver_id
        

 查詢的場景是這樣的: 司機表和訂單表的數據,需要展示在訂單表已經有的司機,如果司機是已經完單,則顯示為空閑,然后可以繼續給改司機派單子。如果是已經出發,需要顯示當前司機是已出發、已到達或者已經完成這樣的狀態。所以需要顯示當前有訂單的司機以及空閑的司機。

但是用上面的sql  使用執行計划查看:

 

 

主要問題出現在下面的union的 left join 。 因為要查詢出來空閑的司機,剛開始使用了inner join ,但是發現數據不准確。發現這個慢sql 后,聯系到場景是 要展示空閑的司機的,那么這個訂單表

其實沒必要全表掃描的,只需要查詢一條即可。於是改為這樣

 

SELECT  t.city_id as cityId,t.city_name as cityName, t.group_id as groupId, t.supplier_name as supplierName,t.id,t.driver_name as driverName,t.license_plates as licensePlates,t.driver_id as driverId,
    t.driver_phone as driverPhone,
    case WHEN m.`status`=1 THEN m.main_order_no  ELSE '' END mainOrder,
    case WHEN m.`status`=1 THEN m.main_name  ELSE '' END subRouteName,
    case WHEN m.`status`=1 THEN m.main_time  ELSE '' END mainOrderTime
    FROM main_order_inter_city m inner JOIN  driver_info_inter_city t
    on t.driver_id =  m.driver_id
    WHERE 1=1   and m.status=1 and t.status =1
        
        UNION
      SELECT t.city_id as cityId,t.city_name as cityName, t.group_id as groupId, t.supplier_name as supplierName,t.id,t.driver_name as driverName,t.license_plates as licensePlates,t.driver_id as driverId,
    t.driver_phone as driverPhone,
    case WHEN m.`status`=1 THEN '' ELSE '' END mainOrder,
    case WHEN m.`status`=1 THEN ''  ELSE '' END subRouteName,
    case WHEN m.`status`=1 THEN ''  ELSE '' END mainOrderTime
    FROM driver_info_inter_city t left JOIN   (SELECT *  FROM main_order_inter_city WHERE id = 1 ) m  
    on t.driver_id =  m.driver_id
    WHERE  1=1  and t.status =1   

    GROUP BY t.driver_id

 

查詢結果和上面的一樣的,sql執行計划

 

 

 

問題解決 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM