最近,我编写了如下的SQL查询:
SELECT DESCR, ip, CPUCpuUtil_day, CPUWio_day
FROM (SELECT res.res_descr DESCR,
node.ip ip,
(ifnull(ROUND(max(CASE WHEN kpi_no = 100000041 THEN k.valuemax END), 2), 0)) CPUCpuUtil_day,
(ifnull(ROUND(max(CASE WHEN kpi_no = 100000041 THEN k.valuemax END), 2), 0)) CPUWio_day
FROM res_object res
LEFT JOIN (SELECT res.res_id, p.kbp, p.valuemax, p.time_id, p.kpi_no
FROM res_object res
LEFT JOIN pm_day_p_reshost p ON p.kbp = res.res_id
AND (p.kpi_no = 100000041 OR p.kpi_no = 100000041) WHERE res.classname = 'ResHost'
AND p.time_id >= '20180913'
AND p.time_id < '20180914') k ON k.res_id = res.res_id, res_node node, res_multiselect rs, res_dim_os os
WHERE rs.multiselect_id = res.multiselect_id
AND node.res_id = res.res_id
AND os.os_id = node.os_id
AND OS.DESCR = 'Linux'
GROUP BY res.res_descr, node.ip) x
由于海量数据,此查询将需要一分钟以上的时间才能显示数据。但是,如果我添加UNION ALL语句:UNION ALL SELECT 1 res_id, 1 valuemax, 1 kbp, 1 time_id, 1 kpi_no
或在AND p.time_id >= '20180913' AND p.time_id < '20180914'
之后将获得0行的UNION ALL语句,此查询将在三秒钟内完成。
那为什么会这样呢?添加这样的UNION ALL语句后,为什么这么快?
我不知道它的原理。
任何答案将不胜感激。
答案 0 :(得分:0)
这只是一个建议(但要发表评论则很复杂)
查看原始查询似乎您有一些奇怪的编码
什么意思是用逗号分隔的列 k ON k.res_id = res.res_id,res_node节点,res_multiselect rs,res_dim_os os
假设您要在where条件下混合显式联接和隐式联接sintax basec。您应该只使用显式连接sintax,而不应使用较旧的隐式sintax
,并且对于内部左联接中的左联接表列,您具有WHERE条件,如果您在何处使用左联接表,则这些联接将作为INNER JOIN ..
(并且您选择两个时间相同的值,但具有不同的列别名CPUCpuUtil_day和CPUWio_day)
您的查询可以重构为
SELECT DESCR
, ip
, CPUCpuUtil_day
, CPUWio_day
FROM (
SELECT res.res_descr DESCR
, node.ip ip
, (ifnull(ROUND(max(CASE WHEN kpi_no = 100000041
THEN k.valuemax END), 2), 0)) CPUCpuUtil_day
, (ifnull(ROUND(max(CASE WHEN kpi_no = 100000041
THEN k.valuemax END), 2), 0)) CPUWio_day
FROM res_object res
LEFT JOIN (
SELECT res.res_id
, p.kbp
, p.valuemax
, p.time_id
, p.kpi_no
FROM res_object res
INNER JOIN pm_day_p_reshost p ON p.kbp = res.res_id
AND (p.kpi_no = 100000041 OR p.kpi_no = 100000041)
AND res.classname = 'ResHost'
AND p.time_id >= '20180913'
AND p.time_id < '20180914'
) k ON k.res_id = res.res_id
INNER JOIN res_multiselect rs ON rs.multiselect_id = res.multiselect_id
INNER JOIN res_node node ON node.res_id = res.res_id
INNER JOIN res_dim_os os ON os.os_id = node.os_id
AND OS.DESCR = 'Linux'
GROUP BY res.res_descr, node.ip
) x