有人可以帮助优化SQL查询

时间:2014-02-19 11:15:56

标签: sql sql-server sql-server-2008 sql-server-2008-r2

SELECT RC.Name AS RiskCategory,
( SELECT 
        SUM(CASE WHEN IA.ImpactLevel = 'High' THEN 1 ELSE 0 END)
        FROM
        Rpt_ImpactAssess IA
        JOIN 
        Rpt_Risk R 
        ON
        IA.FKRiskID  =  R.RiskID
        WHERE
        R.RiskID IN
        (
          SELECT FKRiskID    
          FROM 
          Rpt_Impact 
          WHERE FKItemID =38
        )
        AND
        R.RiskCatrogry = RC.Name        
    )AS High_Impact_Risks

From RM_RiskCategories RC
WHERE
RC.Name <> 'All'
GROUP BY 
RC.Name 
ORder By 
RC.Name DESC 

4 个答案:

答案 0 :(得分:1)

我很确定这会产生相同的结果,试试看:

SELECT RC.Name AS RiskCategory,
       SUM(CASE WHEN IA.ImpactLevel = 'High' 
                THEN 1 
                ELSE 0 
           END)
FROM RM_RiskCategories RC
LEFT JOIN Rpt_Risk R ON R.RiskCatrogry = RC.Name 
LEFT JOIN Rpt_ImpactAssess IA ON IA.FKRiskID = R.RiskID
WHERE RC.Name <> 'All' 
  AND ( R.RiskID IS NULL 
     OR R.RiskID IN (SELECT FKRiskID    
                     FROM Rpt_Impact 
                     WHERE FKItemID = 38) )
GROUP BY RC.Name 
ORDER BY RC.Name DESC 

由于你需要所有的类别(我最初错过的一点)你的原始查询实际上可能是一个非常好的方式 - 我真的不喜欢使用LEFT JOIN ... WHERE pk IS NULL OR pk = something,就像我不得不 - 所以你肯定需要对上面的内容进行基准测试,看它是否真的更好。

您可以将该子查询转换为JOIN,但我不确定是否会有任何性能提升。仍然值得测试,从WHERE子句中删除子查询,然后添加另一个LEFT JOIN

LEFT JOIN Rpt_ImpactAssess IA ON IA.FKRiskID = R.RiskID
WHERE ... AND (R.RiskID IS NULL OR RI.FKItemID = 38)

答案 1 :(得分:0)

试试这个,抱歉语法如果any.it肯定会比那个子查询更快。还要尝试创建相关索引。也知道这一点,哪个表返回多少行加入然后相应你可以在CTR中打破它们.sometime it help.Also你非常正确地使用sum而不是count

SELECT RC.Name AS RiskCategory,SUM(CASE WHEN IA.ImpactLevel = 'High' THEN 1 ELSE 0 END)High_Impact_Risks
From RM_RiskCategories RC
inner join Rpt_Risk R on  R.RiskCatrogry = RC.Name 
inner join Rpt_ImpactAssess IA on IA.FKRiskID  =  R.RiskID
inner join dbo.Rpt_Impact R1 on R.RiskID=R1.FKRiskID and R1.FKItemID =38
WHERE
RC.Name <> 'All'
GROUP BY 
RC.Name 
ORder By 
RC.Name DESC 

答案 2 :(得分:0)

检查这是否能为您提供预期的结果:

SELECT RC.Name AS RiskCategory,
SUM(CASE WHEN IA.ImpactLevel = 'High' THEN 1 ELSE 0 END) AS High_Impact_Risks
From RM_RiskCategories RC LEFT JOIN Rpt_Risk R
ON R.RiskCatrogry = RC.Name
INNER JOIN Rpt_ImpactAssess IA
ON IA.FKRiskID  =  R.RiskID
AND R.RiskID IN
    (
      SELECT FKRiskID    
      FROM 
      Rpt_Impact 
      WHERE FKItemID =38
    )
WHERE
RC.Name <> 'All'
GROUP BY 
RC.Name 
ORder By 
RC.Name DESC

如果不存在,我建议您检查和添加的其他一些内容包括:

  1. Rpt_Impact上的聚簇索引(FKItemID)
  2. Rpt_Risk(RiskID)上的聚簇索引
  3. RM_RiskCategories(名称)上的聚簇索引
  4. Rpt_Risk上的非聚集索引(RiskCatrogry)
  5. Rpt_ImpactAccess(FKRiskID)上的聚簇索引
  6. Rpt_ImpactAccess上的非聚集索引(FKRiskID)INCLUDE(ImpactLevel)

答案 3 :(得分:0)

感谢您的帮助和解答。在您的帮助下,我能够找出我的查询,如下所示:

SELECT RC.Name AS RiskCategory, SUM(IA.ImpactLevel ='High'THEN 1 ELSE 0 END时的情况)AS High_Impact_Risks 来自RM_RiskCategories RC LEFT JOIN Rpt_Risk R. ON R.RiskCatrogry = RC.Name LEFT JOIN Rpt_ImpactAssess IA ON IA.FKRiskID = R.RiskID AND R.RiskID IN     (       SELECT FKRiskID
      从       Rpt_Impact       在哪里FKItemID = 38     ) 哪里 RC.Name&lt;&gt; '所有' 通过...分组 RC.Name 订购者 RC.Name DESC