改进 MySQL 联合声明
Improve MySQL Union Statement
我有以下 mySql 语句,我确信它可以变得更有效率,我只是不确定什么是最好的方法......唯一的区别是 equip_id 在 WHERE 子句中发生变化...
==============
(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 秒...
给我指明正确的方向??
谢谢!
我会使用 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
检查数据是否重复删除,消耗更多进程。
首先,您应该使用 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)
.
上创建一个索引
我有以下 mySql 语句,我确信它可以变得更有效率,我只是不确定什么是最好的方法......唯一的区别是 equip_id 在 WHERE 子句中发生变化...
==============
(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 秒...
给我指明正确的方向??
谢谢!
我会使用 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
检查数据是否重复删除,消耗更多进程。
首先,您应该使用 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)
.