首页 > 解决方案 > 关于“UNION ALL”语句的问题,MYSQL

问题描述

最近,我写了一个 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或 UNION ALL 语句,该语句将在 之后获得 0 行AND p.time_id >= '20180913' AND p.time_id < '20180914',则此查询将在 3 秒内完成。
那么为什么会这样呢?为什么加了这样一条UNION ALL语句后这么快?
我想知道它的原理。
任何答案将不胜感激。

标签: mysqlsql

解决方案


这只是一个建议(但要复杂的评论)

查看您的原始查询似乎您有一些奇怪的编码

k ON k.res_id = res.res_id, res_node node, res_multiselect rs, res_dim_os os 中用逗号分隔的列是什么意思

假设您在 where 条件下混合显式连接和隐式连接 sintax basec。你应该只使用显式连接sintax,而不是旧的隐式sintax

并且您在左内连接中具有左连接表列的 WHERE 条件,如果您将 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

推荐阅读