如何提高此存储过程的性能

时间:2018-03-29 21:40:14

标签: sql sql-server query-performance execution-time

下面是存储过程的动态查询结果,它使用join从视图和其他表中获取记录,如下所示。它只获取5行,但需要13秒才能执行。我需要减少执行时间。

我怎样才能实现这一目标?我已经使用了执行计划,在此查询中使用的表中没有丢失索引。建议任何其他方式。我还分析了这个视图需要花费很多时间来执行,有没有办法改善视图性能呢?

DECLARE @MonthId int

SELECT TOP 1 
    @MonthId = Month_Id 
FROM
    CVBAT_Mart.dbo.Fact_AE_CurrentMonth WITH (NOLOCK)

SELECT    
    Site_Churn_Cd    
    ,SUM(FAE.Site_Count) AS Site_Count    
    ,SUM(FAE.Account_Count) AS Account_Count        
    ,FORMAT(SUM(TY_DailyVolume),'0,0,') as TY_ADV    
    ,FORMAT(SUM(LY_DailyVolume),'0,0') as LY_ADV    
    ,Site_Churn_Cd_color =    
              CASE WHEN Site_Churn_Cd = 'D' THEN 'f8bd19'    
                   WHEN Site_Churn_Cd = 'G' THEN '33ccff'    
                   WHEN Site_Churn_Cd = 'L' THEN 'ccff66'    
                   WHEN Site_Churn_Cd = 'N' THEN 'ffcccc'    
                   WHEN Site_Churn_Cd = 'U' THEN 'c0c0c0'    
                   ELSE Site_Churn_Cd 
              END
FROM 
    CVBAT_Mart.dbo.vFact_AE_Service_Category_TT FAE WITH (NOLOCK)     
INNER JOIN 
    common_ESTAT.dbo.SR_Hierarchy_ESTAT_Promoted_Monthly ESTAT WITH (NOLOCK) ON FAE.Enprs_Employee_Id = ESTAT.SR_Level_1_ID 
WHERE 
    c_Excluded_Flag = 'N'    
    AND c_Site_Primary_AE = '1'    
    AND FAE.Month_Id = @MonthId      
    AND Customer_Shipment_Role_Cd = '03'    
    AND EXISTS (SELECT 1         
                FROM CVBAT_Mart.dbo.DIM_Geography DG WITH (NOLOCK)    
                WHERE Organization_Active_Ind = 1    
                  AND DG.Region_Num = ESTAT.SR_Level_1_Region_Num    
                  AND DG.District_Num = ESTAT.SR_Level_1_District_Num)
  GROUP BY    
      Site_Churn_Cd

2 个答案:

答案 0 :(得分:1)

没有执行计划和/或其他架构数据,还有很多工作要做。 EXISTS可能会导致性能问题,并且应该可以通过JOIN条件进行替换。我不认为这会解决你的问题,但无论如何都要尝试。

发布此类查询时,请确保为所有字段添加别名。这些别名有助于暗示一些架构信息,尽管它不如实际的架构数据好。

DECLARE @MonthId INT
SELECT  TOP 1
        @MonthId = Month_Id
FROM    CVBAT_Mart.dbo.Fact_AE_CurrentMonth WITH (NOLOCK)

SELECT  Site_Churn_Cd,
        SUM( FAE.Site_Count ) AS Site_Count,
        SUM( FAE.Account_Count ) AS Account_Count,
        FORMAT( SUM( TY_DailyVolume ), '0,0,' ) AS TY_ADV,
        FORMAT( SUM( LY_DailyVolume ), '0,0' ) AS LY_ADV,
        Site_Churn_Cd_color = CASE
                                  WHEN Site_Churn_Cd = 'D' THEN 'f8bd19'
                                  WHEN Site_Churn_Cd = 'G' THEN '33ccff'
                                  WHEN Site_Churn_Cd = 'L' THEN 'ccff66'
                                  WHEN Site_Churn_Cd = 'N' THEN 'ffcccc'
                                  WHEN Site_Churn_Cd = 'U' THEN 'c0c0c0'
                                  ELSE Site_Churn_Cd
                              END
FROM    CVBAT_Mart.dbo.vFact_AE_Service_Category_TT AS FAE WITH (NOLOCK)
JOIN    common_ESTAT.dbo.SR_Hierarchy_ESTAT_Promoted_Monthly AS ESTAT WITH (NOLOCK)
    ON  ESTAT.SR_Level_1_ID = FAE.Enprs_Employee_Id
JOIN    CVBAT_Mart.dbo.DIM_Geography AS DG WITH (NOLOCK)
    ON  DG.Organization_Active_Ind = 1
    AND DG.Region_Num = ESTAT.SR_Level_1_Region_Num
    AND DG.District_Num = ESTAT.SR_Level_1_District_Num
WHERE   c_Excluded_Flag = 'N'
    AND c_Site_Primary_AE = '1'
    AND Customer_Shipment_Role_Cd = '03'
    AND FAE.Month_Id = @MonthId
GROUP BY Site_Churn_Cd

答案 1 :(得分:0)

您提到查询只返回5行,但请注意,查询是跨越两个表的行的聚合。查询的性能将与应用聚合之前的行数成比例。您可以基于此而不是使用最终的聚合行计数来计算所花费的时间。

让我们暂时假设即使在聚合之前,行数也是合理的。在这种情况下,您需要确保拥有正确的索引集以方便WHERE条件,JOIN和EXISTS。这是查看查询的执行计划将指导您的地方。

您甚至可以将查询分解为每个阶段的每个阶段检查绩效。我注意到查询中涉及的第一个表实际上是一个视图,通过命名。视图可能是另一组表连接。

总的来说,您最好的选择是按步骤构建查询,并检查每个步骤中有关索引的任何优化。能够阅读和理解查询执行计划对于获得最佳结果至关重要。