zoukankan      html  css  js  c++  java
  • 记录一次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执行计划

     

    问题解决 

  • 相关阅读:
    字符串时间+8个小时
    Django的field字段与参数介绍
    celery+Django
    二分查找
    排序算法
    socket套接字
    网络七层协议简述
    ORM操作mysql数据库多表的增删改查
    ORM操作mysql数据库
    Django框架静态文件配置和URL解析
  • 原文地址:https://www.cnblogs.com/thinkingandworkinghard/p/12330284.html
Copyright © 2011-2022 走看看