2016-11-22 21 views
-1

我有一个查询,有LEFT OUTER JOIN和一些嵌套查询,我怎么可以重写它(优化它的辩论,因为该变种的查询时间是太糟糕了(超过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 

任何我试图删除在左加入子查询,但我有一个错误的地方,最后它没有正确地考虑金额

我重建不起作用:

#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查询1结果: enter image description here

会很乐意的如何解决此类问题的几个例子,它是一个多LEFT JOIN的和WHERE它

+0

您使用的是mysql还是sql server?如果是sql server,那么如果你可以把你的执行计划放在www.pastetheplan.com上给我们的链接,它会有很大的帮助。 –

+0

使用MySQL 5.6 –

+0

首先要弄清楚哪些RDBMS你使用。然后参见http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple-sql-询问 – Strawberry

回答

0

条件JOIN子句是不正确的。在原始查询中,分别针对每个记录执行子查询。如果您使用联接,则必须将所有计算提供为记录集。是(仅适用于“t_emergency_requests”“characterCode”?)还要求现场的JOIN操作。在你的第二个查询,这些连接都没有接通子句的子查询在一个有效的参考。 注:我已经检查了查询只用于其语法的正确性,因为表缺失。

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 
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>