在不使用嵌套查询的情况下优化查询,是真的吗?

时间:2016-11-22 08:51:45

标签: mysql sql join

我有一个查询,它有LEFT OUTER JOIN和一些嵌套查询,如何重写它(优化它,cuz查询时间太差(超过100秒):

SELECT 
    catalog_requests_character_group_for_report.name as nameGroup, 
    catalog_requests_character_group.name as nameFirst, 
    catalog_requests_character.name as nameSecond,
    catalog_requests_character_group.characterGroupCode as characterGroupCode, 
    catalog_requests_character.characterCode as characterCode,  
    (SELECT count(subscriberNumber) FROM t_emergency_requests WHERE (subscriberNumber>-1 and capacityFlag=false)   AND t_emergency_requests.characterCode=catalog_requests_character.characterCode AND  startDate >= '2015-11-01' AND startDate <= '2016-11-30') AS countGas, 
    (SELECT count(subscriberBalloonNumber) FROM t_emergency_requests WHERE (subscriberBalloonNumber>-1 or capacityFlag=true)  AND t_emergency_requests.characterCode=catalog_requests_character.characterCode  AND catalog_requests_character.characterGroupForReportCode= catalog_requests_character_group_for_report.characterGroupForReportCode AND  startDate >= '2015-11-01' AND startDate <= '2016-11-30') AS countBalloon, 
    (SELECT count(subscriberNumber) FROM t_emergency_requests WHERE (subscriberNumber>-1 and capacityFlag=false)   AND t_emergency_requests.characterCode=catalog_requests_character.characterCode AND detectedCode=0 AND  startDate >= '2015-11-01' AND startDate <= '2016-11-30') AS countGasUnjustified, 
    (SELECT count(subscriberBalloonNumber) FROM t_emergency_requests WHERE (subscriberBalloonNumber>-1 or capacityFlag=true)  AND t_emergency_requests.characterCode=catalog_requests_character.characterCode  AND catalog_requests_character.characterGroupForReportCode= catalog_requests_character_group_for_report.characterGroupForReportCode  AND detectedCode=0 AND  startDate >= '2015-11-01' AND startDate <= '2016-11-30') AS countBalloonUnjustified 
FROM catalog_requests_character_group_for_report, catalog_requests_character LEFT OUTER JOIN  catalog_requests_character_group  ON catalog_requests_character.characterGroupCode= catalog_requests_character_group.characterGroupCode 
LEFT OUTER JOIN t_emergency_requests ON catalog_requests_character.characterCode= t_emergency_requests.characterCode WHERE catalog_requests_character.characterGroupForReportCode= catalog_requests_character_group_for_report.characterGroupForReportCode GROUP BY nameSecond

任何想法如何让它更快?我试图删除LEFT JOIN中的子查询,但我在某处出错,最后它没有正确考虑金额

我的重建不起作用:

#catalog_requests_character as a
#catalog_requests_character_group_for_report as b
#catalog_requests_character_group as c
#t_emergency_requests as d
SELECT
    b.NAME AS nameGroup,
    c.NAME AS nameFirst,
    a.NAME AS nameSecond,
    c.characterGroupCode AS characterGroupCode,
    a.characterCode AS characterCode, Gas.countGas, Ballon.countBalloon, CGas.countGasUnjustified, CBalloon.countBallonUnjustified
FROM
    catalog_requests_character as a

INNER JOIN catalog_requests_character_group_for_report as b ON a.characterGroupForReportCode = b.characterGroupForReportCode 

LEFT OUTER JOIN catalog_requests_character_group as c ON a.characterGroupCode = c.characterGroupCode

LEFT OUTER JOIN t_emergency_requests as d ON a.characterCode = d.characterCode

LEFT JOIN (SELECT
            count(subscriberNumber) as countGas
        FROM
            t_emergency_requests
        WHERE
            (
                subscriberNumber >- 1
                AND capacityFlag = FALSE
            )
        AND startDate >= '2016-11-01'
        AND startDate <= '2016-11-30') Gas ON a.characterCode = d.characterCode 

LEFT JOIN (SELECT
            count(subscriberBalloonNumber) as countBalloon
        FROM
            t_emergency_requests
        WHERE
            (
                subscriberBalloonNumber >- 1
                OR capacityFlag = TRUE
            )
        AND startDate >= '2016-11-01'
        AND startDate <= '2016-11-30') Ballon ON (a.characterCode = d.characterCode AND a.characterGroupForReportCode = b.characterGroupForReportCode)

LEFT JOIN (SELECT
            count(subscriberNumber) as countGasUnjustified
        FROM
            t_emergency_requests
        WHERE
            (
                subscriberNumber >- 1
                AND capacityFlag = FALSE
            )
        AND detectedCode = 0
        AND startDate >= '2016-11-01'
        AND startDate <= '2016-11-30') CGas ON a.characterCode = d.characterCode 

LEFT JOIN (SELECT
            count(subscriberBalloonNumber) as countBallonUnjustified
        FROM
            t_emergency_requests
        WHERE
            (
                subscriberBalloonNumber >- 1
                OR capacityFlag = TRUE
            )
        AND detectedCode = 0
        AND startDate >= '2016-11-01'
        AND startDate <= '2016-11-30') CBalloon ON (a.characterCode = d.characterCode AND a.characterGroupForReportCode = b.characterGroupForReportCode)

GROUP BY
    nameSecond
ORDER BY 
    nameGroup

#catalog_requests_character as a #catalog_requests_character_group_for_report as b #catalog_requests_character_group as c #t_emergency_requests as d SELECT b.NAME AS nameGroup, c.NAME AS nameFirst, a.NAME AS nameSecond, c.characterGroupCode AS characterGroupCode, a.characterCode AS characterCode, Gas.countGas, Ballon.countBalloon, CGas.countGasUnjustified, CBalloon.countBallonUnjustified FROM catalog_requests_character as a INNER JOIN catalog_requests_character_group_for_report as b ON a.characterGroupForReportCode = b.characterGroupForReportCode LEFT OUTER JOIN catalog_requests_character_group as c ON a.characterGroupCode = c.characterGroupCode LEFT OUTER JOIN t_emergency_requests as d ON a.characterCode = d.characterCode LEFT JOIN (SELECT count(subscriberNumber) as countGas FROM t_emergency_requests WHERE ( subscriberNumber >- 1 AND capacityFlag = FALSE ) AND startDate >= '2016-11-01' AND startDate <= '2016-11-30') Gas ON a.characterCode = d.characterCode LEFT JOIN (SELECT count(subscriberBalloonNumber) as countBalloon FROM t_emergency_requests WHERE ( subscriberBalloonNumber >- 1 OR capacityFlag = TRUE ) AND startDate >= '2016-11-01' AND startDate <= '2016-11-30') Ballon ON (a.characterCode = d.characterCode AND a.characterGroupForReportCode = b.characterGroupForReportCode) LEFT JOIN (SELECT count(subscriberNumber) as countGasUnjustified FROM t_emergency_requests WHERE ( subscriberNumber >- 1 AND capacityFlag = FALSE ) AND detectedCode = 0 AND startDate >= '2016-11-01' AND startDate <= '2016-11-30') CGas ON a.characterCode = d.characterCode LEFT JOIN (SELECT count(subscriberBalloonNumber) as countBallonUnjustified FROM t_emergency_requests WHERE ( subscriberBalloonNumber >- 1 OR capacityFlag = TRUE ) AND detectedCode = 0 AND startDate >= '2016-11-01' AND startDate <= '2016-11-30') CBalloon ON (a.characterCode = d.characterCode AND a.characterGroupForReportCode = b.characterGroupForReportCode) GROUP BY nameSecond ORDER BY nameGroup

EXPLAIN Query1结果: enter image description here

会很高兴看到如何解决这些问题的几个例子,它有多个LEFT JOIN和WHERE条件

2 个答案:

答案 0 :(得分:0)

JOIN子句不正确。在原始查询中,分别为每个记录执行子查询。如果使用连接,则必须将所有计算作为记录集提供。 JOIN操作也需要该字段(“characterCode”仅在“t_emergency_requests”中?)。在第二个查询中,JOINS在其子查询的ON子句中没有有效的引用。 注意:我只检查了查询的语法正确性,因为缺少表。

    SELECT b.NAME AS nameGroup,
       c.NAME AS nameFirst,
       a.NAME AS nameSecond,
       c.characterGroupCode AS characterGroupCode,
       a.characterCode AS characterCode, Gas.countGas, Ballon.countBalloon, CGas.countGasUnjustified, CBalloon.countBallonUnjustified
  FROM catalog_requests_character as a

       INNER JOIN catalog_requests_character_group_for_report as b 
               ON a.characterGroupForReportCode = b.characterGroupForReportCode 

        LEFT JOIN catalog_requests_character_group as c 
               ON a.characterGroupCode = c.characterGroupCode

        LEFT JOIN t_emergency_requests as d 
               ON a.characterCode = d.characterCode

        LEFT JOIN (SELECT characterCode,
                          count(subscriberNumber) as countGas
                     FROM t_emergency_requests
                    WHERE (subscriberNumber >- 1 AND capacityFlag = FALSE)
                      AND startDate >= '2016-11-01'
                      AND startDate <= '2016-11-30'
                    GROUP BY characterCode) Gas 
               ON Gas.characterCode = d.characterCode

        LEFT JOIN (SELECT characterCode,
                          count(subscriberBalloonNumber) as countBalloon
                     FROM t_emergency_requests
                    WHERE (subscriberBalloonNumber >- 1 OR capacityFlag = TRUE)
                      AND startDate >= '2016-11-01'
                      AND startDate <= '2016-11-30'
                    GROUP BY characterCode) Ballon 
               ON Ballon.characterCode = d.characterCode

        LEFT JOIN (SELECT characterCode,
                          count(subscriberNumber) as countGasUnjustified
                     FROM t_emergency_requests
                    WHERE (subscriberNumber >- 1 AND capacityFlag = FALSE)
                      AND detectedCode = 0
                      AND startDate >= '2016-11-01'
                      AND startDate <= '2016-11-30') CGas
               ON CGas.characterCode = d.characterCode

        LEFT JOIN (SELECT characterCode,
                          count(subscriberBalloonNumber) as countBallonUnjustified
                     FROM t_emergency_requests
                    WHERE (subscriberBalloonNumber >- 1 OR capacityFlag = TRUE)
                      AND detectedCode = 0
                      AND startDate >= '2016-11-01'
                      AND startDate <= '2016-11-30') CBalloon
               ON CBallon.characterCode = d.characterCode

 GROUP BY nameSecond
 ORDER BY nameGroup

答案 1 :(得分:0)

感谢您的回答,找到这样的解决方案: 查询时间从100+秒到<2秒 也许这将有助于其他人。使用临时表

<code>
DROP TABLE
IF EXISTS temp_a1;

CREATE TEMPORARY TABLE temp_a1 AS (
    SELECT
        *, count(t_emergency_requests.subscriberNumber) as countSN
    FROM
        t_emergency_requests
    WHERE
        (
            subscriberNumber >- 1
            AND capacityFlag = FALSE
        )
    AND startDate >= '2015-11-01'
    AND startDate <= '2016-11-30'
    GROUP BY
        characterCode
);

DROP TABLE
IF EXISTS temp_b1;

CREATE TEMPORARY TABLE temp_b1 AS (
    SELECT
        t_emergency_requests.characterCode as cCode, catalog_requests_character.*, count(t_emergency_requests.subscriberBalloonNumber) as countSN
    FROM
        t_emergency_requests
    LEFT JOIN catalog_requests_character ON catalog_requests_character.characterCode=t_emergency_requests.characterCode
    WHERE
        (
            subscriberBalloonNumber >- 1
            OR capacityFlag = TRUE
        )
    AND startDate >= '2015-11-01'
    AND startDate <= '2016-11-30'
    GROUP BY
        t_emergency_requests.characterCode, catalog_requests_character.characterGroupForReportCode
);

DROP TABLE
IF EXISTS temp_c1;

CREATE TEMPORARY TABLE temp_c1 AS (
    SELECT
        *, count(t_emergency_requests.subscriberNumber) as countSN
    FROM
        t_emergency_requests
    WHERE
        (
            subscriberNumber >- 1
            AND capacityFlag = FALSE
        )
    AND detectedCode = 0
    AND startDate >= '2015-11-01'
    AND startDate <= '2016-11-30'
    GROUP BY
        characterCode
);

DROP TABLE
IF EXISTS temp_d1;

CREATE TEMPORARY TABLE temp_d1 AS (
    SELECT
        t_emergency_requests.characterCode as cCode, catalog_requests_character.characterGroupForReportCode, count(t_emergency_requests.subscriberBalloonNumber) as countSN
    FROM
        t_emergency_requests
    LEFT JOIN catalog_requests_character ON catalog_requests_character.characterCode=t_emergency_requests.characterCode
    WHERE
        (
            subscriberBalloonNumber >- 1
            OR capacityFlag = TRUE
        )
    AND detectedCode = 0
    AND startDate >= '2015-11-01'
    AND startDate <= '2016-11-30'
    GROUP BY
        t_emergency_requests.characterCode, catalog_requests_character.characterGroupForReportCode
);

DROP TABLE
IF EXISTS alt_temp_a1;
DROP TABLE
IF EXISTS alt_temp_b1;
DROP TABLE
IF EXISTS alt_temp_c1;
DROP TABLE
IF EXISTS alt_temp_d1;

CREATE TEMPORARY TABLE alt_temp_a1 LIKE temp_a1;
CREATE TEMPORARY TABLE alt_temp_b1 LIKE temp_b1;
CREATE TEMPORARY TABLE alt_temp_c1 LIKE temp_c1;
CREATE TEMPORARY TABLE alt_temp_d1 LIKE temp_d1;

SELECT 
        catalog_requests_character_group_for_report.name as nameGroup, 
        catalog_requests_character_group.name as nameFirst, 
        catalog_requests_character.name as nameSecond,
        catalog_requests_character_group.characterGroupCode as characterGroupCode, 
        catalog_requests_character.characterCode as characterCode,  
        (SELECT SUM(countSN) FROM temp_a1 WHERE temp_a1.characterCode=catalog_requests_character.characterCode) AS countGas, 
        (SELECT SUM(countSN) FROM temp_b1 WHERE temp_b1.cCode=catalog_requests_character.characterCode AND catalog_requests_character.characterGroupForReportCode=catalog_requests_character_group_for_report.characterGroupForReportCode) AS countBalloon, 
        (SELECT SUM(countSN) FROM temp_c1 WHERE temp_c1.characterCode=catalog_requests_character.characterCode) AS countGasUnjustified, 
        (SELECT SUM(countSN) FROM temp_d1 WHERE temp_d1.cCode=catalog_requests_character.characterCode AND catalog_requests_character.characterGroupForReportCode=catalog_requests_character_group_for_report.characterGroupForReportCode) AS countBallonUnjustified 
    FROM catalog_requests_character_group_for_report, catalog_requests_character
    LEFT OUTER JOIN  catalog_requests_character_group  ON catalog_requests_character.characterGroupCode= catalog_requests_character_group.characterGroupCode 
    LEFT OUTER JOIN t_emergency_requests ON catalog_requests_character.characterCode= t_emergency_requests.characterCode 
    WHERE catalog_requests_character.characterGroupForReportCode=catalog_requests_character_group_for_report.characterGroupForReportCode 
GROUP BY nameSecond 
UNION ALL
SELECT 
        catalog_requests_character_group_for_report.name as nameGroup,  
        catalog_requests_character_group.name as nameFirst, 
        catalog_requests_character.name as nameSecond, 
        catalog_requests_character_group.characterGroupCode as characterGroupCode, 
        catalog_requests_character.characterCode as characterCode,  
        (SELECT SUM(countSN) FROM alt_temp_a1 WHERE alt_temp_a1.characterCode=catalog_requests_character.characterCode) AS countGas, 
        (SELECT SUM(countSN) FROM alt_temp_b1 WHERE alt_temp_b1.cCode=catalog_requests_character.characterCode AND catalog_requests_character.characterGroupForReportCode=catalog_requests_character_group_for_report.characterGroupForReportCode) AS countBalloon, 
        (SELECT SUM(countSN) FROM alt_temp_c1 WHERE alt_temp_c1.characterCode=catalog_requests_character.characterCode) AS countGasUnjustified, 
        (SELECT SUM(countSN) FROM alt_temp_d1 WHERE alt_temp_d1.cCode=catalog_requests_character.characterCode AND catalog_requests_character.characterGroupForReportCode=catalog_requests_character_group_for_report.characterGroupForReportCode) AS countBalloonUnjustified 
    FROM catalog_requests_character_group_for_report, catalog_requests_character_group 
    LEFT OUTER JOIN catalog_requests_character ON catalog_requests_character.characterGroupCode= catalog_requests_character_group.characterGroupCode 
    LEFT OUTER JOIN t_emergency_requests ON catalog_requests_character_group.characterGroupCode= t_emergency_requests.characterGroupCode WHERE catalog_requests_character_group.characterGroupForReportCode= catalog_requests_character_group_for_report.characterGroupForReportCode 
GROUP BY nameFirst 
ORDER BY nameGroup
</code>
相关问题