如何使用In优化SQL查询

时间:2014-02-23 15:31:55

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

如何优化SQL查询,如下所示?

SELECT COUNT(R.RiskID) AS RiskCount 
FROM   Rpt_Risk R JOIN Rpt_ImpactAssessment IMA  
ON     R.RiskID = IMA.FKRiskID
WHERE  IMA.FKItemID = 38
AND    IMA.ImpactCurPIDLevel LIKE '%High%'
AND    IMA.FKPLanID NOT IN 
                      (
                       SELECT IA.FKPlanID 
                       FROM Rpt_ImpactAssessment IA JOIN RM_LinkActionToPlan LAP  
                       ON IA.FKPlanID = LAP.PlanID  
                       JOIN RM_Action A    
                       ON LAP.ActionID = A.ActionID 
                       AND IA.FKItemID = 38
                       AND IA.ImpactCurPIDLevel LIKE '%High%'
                      )

2 个答案:

答案 0 :(得分:0)

使用分析仪(它的工作原理取决于您的服务器类型) 如果IN查询仅运行一次,则无法根据查询进行优化 如果,它运行主查询中找到的每个记录,你就麻烦了......在这种情况下:

  1. 如果从查询缓存中获取内部查询结果,那没什么大不了的。
  2. 如果内部查询结果只有几百个ID,那么你可以在单独的查询中获取它们,并且只需对参数进行硬编码。
  3. 如果主要查询中的硬代码有太多ID,则一个选项是创建一个包含所有需要的ID的临时表,并简单地JOIN使用主查询。
  4. 真正取决于您的应用程序的编写方式,以提出更多优化建议。

答案 1 :(得分:0)

首先,似乎没有使用risk表,假设两个表中RiskID匹配(因此join没有进行任何过滤)。

其次,您似乎在询问“哪个38 /高计划在LinkActionToPlan表中没有匹配”。如果我有这个权利,您可以简单地将查询简化为:

SELECT COUNT(*) AS RiskCount 
FROM Rpt_ImpactAssessment IMA  
WHERE IMA.FKItemID = 38 AND
      IMA.ImpactCurPIDLevel LIKE '%High%' AND
      NOT EXISTS (select 1
                  from RM_LinkActionToPlan LAP  join
                       RM_Action A
                       on LAP.ActionID = A.ActionID
                  where IMA.FKPlanID = LAP.PlanID
                 );

RM_Action没有过滤,所以我怀疑此表也可以从查询中删除。