邓诺(Dunno)对此还有什么可做的。我有一个具有开始和停止列的表,我想返回通过开始和停止连接的表的结果,我希望两者之间有明显的区别。现在,这两个查询分别快速运行:
SELECT
UNIX_TIMESTAMP(CONVERT_TZ(start_dev, '+00:00', GetCarrierTimezone(a0.carrier_id))) AS alertStart,
NULL AS alertStop,
c0.name AS carrier_name,
carrier_image,
l0.Latitude,
l0.Longitude
FROM
carriers AS c0
INNER JOIN start_stop AS a0 ON a0.carrier_id = c0.id
INNER JOIN pcoarg AS l0 ON a0.startLogId = l0.id
WHERE
FIND_IN_SET(a0.carrier_id, '89467,1,64578,222625,45013') > 0
AND
start_dev > '2013-03-11 11:46:48'
AND
start_dev = (SELECT MIN(start_dev) FROM start_stop AS a1 WHERE a0.carrier_id = a1.carrier_id AND DATE(a1.start_dev) = DATE(a0.start_dev))
AND IsNotificationInSchedule(22, start_dev) > 0
因此,这需要0.063。但是,如果我将其组合成一个UNION(无论是UNION ALL还是DISTINCT或其他都没关系),则只需要0.400秒。
SELECT * FROM
(
(
SELECT
UNIX_TIMESTAMP(CONVERT_TZ(start_dev, '+00:00', GetCarrierTimezone(a0.carrier_id))) AS alertStart,
NULL AS alertStop,
c0.name AS carrier_name,
carrier_image,
l0.Latitude,
l0.Longitude
FROM
carriers AS c0
INNER JOIN start_stop AS a0 ON a0.carrier_id = c0.id
INNER JOIN pcoarg AS l0 ON a0.startLogId = l0.id
WHERE
FIND_IN_SET(a0.carrier_id, '89467,1,64578,222625,45013') > 0
AND
start_dev > '2013-03-11 11:46:48'
AND
start_dev = (SELECT MIN(start_dev) FROM start_stop AS a1 WHERE a0.carrier_id = a1.carrier_id AND DATE(a1.start_dev) = DATE(a0.start_dev))
AND IsNotificationInSchedule(22, start_dev) > 0
) UNION ALL (
SELECT
NULL AS alertStart,
UNIX_TIMESTAMP(CONVERT_TZ(stop_dev, '+00:00', GetCarrierTimezone(a0.carrier_id))) AS alertStop,
c0.name AS carrier_name,
carrier_image,
l0.Latitude,
l0.Longitude
FROM
start_stop AS a0
INNER JOIN carriers AS c0 ON a0.carrier_id = c0.id
INNER JOIN pcoarg AS l0 ON a0.stopLogId = l0.id
WHERE
FIND_IN_SET(a0.carrier_id, '89467,1,64578,222625,45013') > 0
AND
stop_dev > '2013-03-11 11:46:48'
AND
stop_dev = (SELECT MAX(stop_dev) FROM start_stop AS a1 WHERE a0.carrier_id = a1.carrier_id AND DATE(a1.stop_dev) = DATE(a0.stop_dev))
AND IsNotificationInSchedule(22, start_dev) > 0
)
) AS startStops
ORDER BY IF(alertStart IS NULL, alertStop, alertStart)
这是单个查询的解释:
1 PRIMARY c0 ALL PRIMARY 17 Using where
1 PRIMARY a0 ref PRIMARY,startstop_carriers_stopdev_idx,georefidx,startstop_carriers_startdev_idx startstop_carriers_stopdev_idx 4 test_backoffice.c0.id 72 Using where
1 PRIMARY l0 ref id ASC id ASC 4 test_backoffice.a0.startLogId 1 Using where
2 DEPENDENT SUBQUERY a1 ref PRIMARY,startstop_carriers_stopdev_idx,georefidx,startstop_carriers_startdev_idx startstop_carriers_stopdev_idx 4 test_backoffice.a0.carrier_id 72 Using where; Using index
这是JOIN的解释:
1 PRIMARY <derived2> system 0 const row not found
2 DERIVED c0 ALL PRIMARY 17 Using where
2 DERIVED a0 ref PRIMARY,startstop_carriers_stopdev_idx,georefidx,startstop_carriers_startdev_idx startstop_carriers_stopdev_idx 4 test_backoffice.c0.id 72 Using where
2 DERIVED l0 ref id ASC id ASC 4 test_backoffice.a0.startLogId 1 Using where
3 DEPENDENT SUBQUERY a1 ref PRIMARY,startstop_carriers_stopdev_idx,georefidx,startstop_carriers_startdev_idx startstop_carriers_stopdev_idx 4 test_backoffice.a0.carrier_id 72 Using where; Using index
4 UNION c0 ALL PRIMARY 17 Using where
4 UNION a0 ref PRIMARY,startstop_carriers_stopdev_idx,georefidx,startstop_carriers_startdev_idx startstop_carriers_stopdev_idx 4 test_backoffice.c0.id 72 Using where
4 UNION l0 ref id ASC id ASC 4 test_backoffice.a0.stopLogId 1 Using where
5 DEPENDENT SUBQUERY a1 ref PRIMARY,startstop_carriers_stopdev_idx,georefidx,startstop_carriers_startdev_idx startstop_carriers_stopdev_idx 4 test_backoffice.a0.carrier_id 72 Using where; Using index
UNION RESULT <union2,4> ALL
在这一方面的帮助将不胜感激。:)
编辑:
我得到不一致的结果。例如,如果我删除convert_tz并尝试使时区超出并集,则会得到非常快速的结果,但是如果我重命名结果,它将自动下降到相同的性能欠佳查询:
SELECT
*,
GetCarrierTimezone(carrier_id) timezone
FROM
(
这需要0.374s
SELECT
*,
GetCarrierTimezone(carrier_id)
FROM
(
而这需要0.078(大部分是从db到我的机器的延迟)。
最简单的方法是分别运行它们并将结果合并到应用程序中。
—
ypercubeᵀᴹ
嗨,@ ypercube,这让我很烦恼:),但是这样做并维护代码非常丑陋。此外,我仍然必须在php中对结果进行排序。
—
Holderjsm 2013年
我的意思是使用所需的排序来运行2个查询。然后,您只需要在php中合并(无需排序)。
—
ypercubeᵀᴹ
排序不是线性的。查询1的结果可以在查询2的结果之间
—
helderjsm
我不认为@ypercube假设结果不会重叠:“合并”比在php中实现的排序便宜/容易得多。当然,如果可能的话,在SQL中解决该问题将是一个更好的解决方案:)
—
杰克说请尝试topanswers.xyz 2013年