改进MySQL联盟声明

时间:2015-03-04 02:40:39

标签: mysql join union

我有以下mySql语句,我相信它可以提高效率,我只是不确定什么是最好的方法...唯一的区别是WHERE子句中更改的equip_id。 ..

==============

 (SELECT 
        `receipt_ts`, 
        `driver_id`,
        `equip_id`, 
        `pos_lon`, 
        `pos_lat`, 
        `pos_timestamp`  
   FROM `log_messaging` 
  WHERE `equip_id`='207' AND `tran_type`='T.2.12.0' 
  ORDER BY receipt_ts DESC LIMIT 1 ) 

 UNION  

(SELECT 
       `receipt_ts`, 
       `driver_id`, 
       `equip_id`, 
       `pos_lon`, 
       `pos_lat`, 
       `pos_timestamp`  
  FROM `log_messaging` 
 WHERE `equip_id`='212' AND `tran_type`='T.2.12.0' 
 ORDER BY receipt_ts DESC LIMIT 1 ) 

 UNION

  (SELECT 
         `receipt_ts`, 
         `driver_id`, 
         `equip_id`, 
         `pos_lon`, 
         `pos_lat`, 
         `pos_timestamp`  
    FROM `log_messaging`
   WHERE `equip_id`='213' AND `tran_type`='T.2.12.0' 
   ORDER BY receipt_ts DESC LIMIT 1 );

=====

我正在联合每个返回的行,为多个equip_id建立一个max(receipt_ts)数据集。 (我需要获得最新的设备定位。

有时,查询最终会出现100多个独特的equip_id。

我正在努力使查询比现在更快地执行(对于~100 UNIONS约为7秒......如上所述...

指出我正确的方向?

谢谢!

2 个答案:

答案 0 :(得分:1)

我会使用IN子句:

SELECT receipt_ts, driver_id, equip_id, pos_lon, pos_lat, pos_timestamp 
FROM log_messaging a
JOIN (SELECT c.equip_id, max(c.receipt_ts) as receipt
      FROM log_messaging c
      WHERE equip_id in ('207', '212', '213')
        AND tran_type='T.2.12.0'
      GROUP by c.equip_id) b USING(equip_id)
WHERE b.receipt = a.receipt_ts
ORDER BY a.receipt_ts

请注意,如果您真的想使用UNION(我不明白为什么会这样做)但想要优化它,您可以使用UNION ALL作为{UNION 1}}检查重复数据删除的数据,消耗更多的进程。

答案 1 :(得分:1)

首先,您应该使用union all而不是union。所以从这个查询开始:

(SELECT receipt_ts, driver_id, equip_id, pos_lon, pos_lat, pos_timestamp
 FROM log_messaging
 WHERE equip_id = '207' AND tran_type = 'T.2.12.0'
 ORDER BY receipt_ts DESC
 LIMIT 1
) UNION ALL
(SELECT receipt_ts, driver_id, equip_id, pos_lon, pos_lat, pos_timestamp
 FROM log_messaging
 WHERE equip_id = '212' AND tran_type = 'T.2.12.0'
 ORDER BY receipt_ts DESC
 LIMIT 1
) UNION ALL
(SELECT receipt_ts, driver_id, equip_id, pos_lon, pos_lat, pos_timestamp
 FROM log_messaging
 WHERE equip_id = '213' AND tran_type = 'T.2.12.0'
 ORDER BY receipt_ts DESC
 LIMIT 1
) ;

这是一个合理的查询。我建议您在log_messaging(tran_type, equip_id, recipt_ts)上创建一个索引。