0

数据库:sqlserver 2008。下面的查询非常慢。我想让这个野兽跑得更快,重写查询,但我很难过。我可以注释掉所有 sum case 语句和 group by 子句,只留下带有 select sum(0) 和 where 子句的查询外壳,并且性能没有太大变化。所以我很确定问题出在 where 子句上。但是,我不确定如何重写这个来尝试任何其他替代方案。

有人想在这个上测试他们的 SQL-fu 吗?任何帮助深表感谢。谢谢!

    INSERT INTO [_SOC_Reviews]
DECLARE
    @LocationID         Int=NULL,
    @FromDate           DateTime=NULL,
    @ToDate             DateTime=NULL,
    @DateType           Int=0,
    @OfficeID           Int=NULL,
    @QCType             Int=NULL,
    @ProgramTypeID      Int=NULL,
    @SupervisorID       varchar(100)=NULL,
    @SpecialistID       varchar(100)=NULL,
    @ReviewerID         varchar(100)=NULL,
    @PrincipalActionID  Int=NULL,
    @DepartmentID       Int=NULL,
    @Group1             Int=1,
    @Group2             Int=1,
    @ReportName         VarChar(100)='rptQC',
    @UserName           varchar(30)=NULL

select 
    @LocationID=NULL,
    @FromDate='2012-05-01 00:00:00',
    @ToDate='2012-06-01',
    @OfficeID=NULL,
    @ProgramTypeID=NULL,
    @SupervisorID=NULL,
    @SpecialistID=NULL,
    @PrincipalActionID=NULL,
    @QCType=NULL,
    @Group1=1,
    @Group2=NULL,
    @UserName=N'joeblow',
    @DepartmentID=NULL,
    @ReviewerID=NULL

IF OBJECT_ID('dbo.[_SOC_Reviews]', 'U') IS NOT NULL
  DROP TABLE dbo.[_SOC_Reviews]
CREATE TABLE [_SOC_Reviews] (
    IsReviewed                  int,
    Group1                      Varchar(100),
    Group2                      Varchar(100),
    NumFilesAssigned            int,
    NumFilesInProgress          int,
    TotalNumFiles               int,
    PendingCorrections          int,
    PendingCorrGT30             int
    )


select SUM(0),
        CASE 
            WHEN @Group1 = 1 THEN CONVERT(Varchar(100), R.LocationID)
            WHEN @Group1 = 2 THEN CONVERT(Varchar(100), R.SubLocation)
            WHEN @Group1 = 3 THEN CONVERT(Varchar(100), R.ProgramTypeID)
            WHEN @Group1 = 4 THEN CONVERT(Varchar(100), RS.SupervisorID)
            WHEN @Group1 = 5 THEN CONVERT(Varchar(100), R.TransactionTypeId)
            WHEN @Group1 = 6 THEN CONVERT(Varchar(100), RS.SpecialistID)
            WHEN @Group1 = 7 THEN CONVERT(Varchar(100), R.ChecklistTypeId)
            WHEN @Group1 = 8 THEN CONVERT(Varchar(100), RS.DepartmentID)
            WHEN @Group1 = 9 THEN CONVERT(Varchar(2), DATEPART(MONTH,R.EffectiveActionDate)) + '/' + CONVERT(VARCHAR(4),DATEPART(YEAR,R.EffectiveActionDate))
            WHEN @Group1 = 10 THEN CONVERT(Varchar(100), R.ReviewedBy)
        END,
        CASE 
            WHEN @Group2 = 1 THEN CONVERT(Varchar(100), R.SubLocation)
            WHEN @Group2 = 2 THEN CONVERT(Varchar(100), R.ProgramTypeID)
            WHEN @Group2 = 3 THEN CONVERT(Varchar(100), RS.SupervisorID)
            WHEN @Group2 = 4 THEN CONVERT(Varchar(100), RS.SpecialistID) 
            WHEN @Group2 = 5 THEN CONVERT(Varchar(100), R.TransactionTypeId)
            WHEN @Group2 = 6 THEN CONVERT(Varchar(100), R.LocationID)
            WHEN @Group2 = 7 THEN CONVERT(Varchar(100), R.ChecklistTypeId)
            WHEN @Group2 = 8 THEN CONVERT(Varchar(100), RS.DepartmentID)
            WHEN @Group2 = 9 THEN CONVERT(Varchar(2), DATEPART(MONTH,R.EffectiveActionDate)) + '/' + CONVERT(VARCHAR(4),DATEPART(YEAR,R.EffectiveActionDate))
            WHEN @Group2 = 10 THEN CONVERT(Varchar(100), R.ReviewedBy) 
            ELSE NULL
        END,
    SUM(CASE WHEN R.ReviewStatusId = 7 AND (R.ReviewStatusModified BETWEEN @FromDate AND @ToDate) THEN 1 ELSE 0 END) AS NumberOfFilesAssigned,
    SUM(CASE WHEN R.ReviewStatusId = 1 AND (R.ReviewStatusModified BETWEEN @FromDate AND @ToDate) THEN 1 ELSE 0 END) as NumberOfFilesInProgress,
    SUM(CASE WHEN (R.ReviewStatusModified BETWEEN @FromDate AND @ToDate) THEN 1 ELSE 0 END) AS TotalNumFiles,
    SUM(CASE WHEN R.ReviewStatusId IN (10,12,14,16) THEN 1 ELSE 0 END),
    SUM(CASE WHEN R.ReviewStatusId IN (10,12,14,16) AND DATEDIFF(DAY, R.InitialCompletionDate, GETDATE()) > 30  THEN 1 ELSE 0 END)

from Review R 
LEFT JOIN   dbo.fnu_ReviewSpecialists2_TEST(@SpecialistID,@SupervisorID,@DepartmentID) RS
    ON  R.Id = RS.ReviewId
    LEFT JOIN Location L
    ON R.LocationId = L.Id
    INNER JOIN  [_SOC_USER] U
    ON R.LocationID = U.LocationID
where 
    ((R.LocationID = @LocationID AND @LocationID IS NOT NULL) OR (@LocationID IS NULL))
    AND ((R.SubLocation = @OfficeID AND @OfficeID IS NOT NULL) or (@OfficeID IS NULL))
    AND ((R.ProgramTypeID = @ProgramTypeID AND @ProgramTypeID IS NOT NULL) or (@ProgramTypeID IS NULL))
    AND ((R.TransactionTypeId = @PrincipalActionID AND @PrincipalActionID IS NOT NULL) or (@PrincipalActionID IS NULL))
    AND ((R.ChecklistTypeId = @QCType AND @QCType IS NOT NULL) OR (@QCType IS NULL))
    AND ((R.ReviewedBy = @ReviewerID AND @ReviewerID IS NOT NULL) or (@ReviewerID IS NULL))
    AND ((RS.SupervisorId = @SupervisorID AND @SupervisorID IS NOT NULL) or (@SupervisorID IS NULL))
    AND ((RS.SpecialistId = @SpecialistID AND @SpecialistID IS NOT NULL) or (@SpecialistID IS NULL))
    AND ((RS.DepartmentId = @DepartmentID AND @DepartmentID IS NOT NULL) or (@DepartmentID IS NULL))
    AND (@LocationID is NOT NULL OR L.IsConsulting = 0)
    AND L.IsActive = 1

GROUP BY  
        CASE
            WHEN @Group1 = 1 THEN CONVERT(Varchar(100), R.LocationID)
            WHEN @Group1 = 2 THEN CONVERT(Varchar(100), R.SubLocation)
            WHEN @Group1 = 3 THEN CONVERT(Varchar(100), R.ProgramTypeID)
            WHEN @Group1 = 4 THEN CONVERT(Varchar(100), RS.SupervisorID)
            WHEN @Group1 = 5 THEN CONVERT(Varchar(100), R.TransactionTypeId)
            WHEN @Group1 = 6 THEN CONVERT(Varchar(100), RS.SpecialistID)
            WHEN @Group1 = 7 THEN CONVERT(Varchar(100), R.ChecklistTypeID)
            WHEN @Group1 = 8 THEN CONVERT(Varchar(100), RS.DepartmentID)
            WHEN @Group1 = 9 THEN CONVERT(Varchar(2), DATEPART(MONTH,R.EffectiveActionDate)) + '/' + CONVERT(VARCHAR(4),DATEPART(YEAR,R.EffectiveActionDate))
            WHEN @Group1 = 10 THEN CONVERT(Varchar(100), R.ReviewedBy)          
        END,
        CASE 
            WHEN @Group2 = 1 THEN CONVERT(Varchar(100), R.SubLocation)
            WHEN @Group2 = 2 THEN CONVERT(Varchar(100), R.ProgramTypeID)
            WHEN @Group2 = 3 THEN CONVERT(Varchar(100), RS.SupervisorID)
            WHEN @Group2 = 4 THEN CONVERT(Varchar(100), RS.SpecialistID) 
            WHEN @Group2 = 5 THEN CONVERT(Varchar(100), R.TransactionTypeId)
            WHEN @Group2 = 6 THEN CONVERT(Varchar(100), R.LocationID)
            WHEN @Group2 = 7 THEN CONVERT(Varchar(100), R.ChecklistTypeId)
            WHEN @Group2 = 8 THEN CONVERT(Varchar(100), RS.DepartmentID)
            WHEN @Group2 = 9 THEN CONVERT(Varchar(2), DATEPART(MONTH,R.EffectiveActionDate)) + '/' + CONVERT(VARCHAR(4),DATEPART(YEAR,R.EffectiveActionDate))
            WHEN @Group2 = 10 THEN CONVERT(Varchar(100), R.ReviewedBy)          
            ELSE NULL
        END 

这是解释计划:

      |--Stream Aggregate(GROUP BY:([Expr1015], [Expr1014]) DEFINE:([Expr1016]=SUM((0)), [Expr1017]=SUM(CASE WHEN [_DatabaseTesta].[dbo].[Review].[ReviewStatusId] as [R].[ReviewStatusId]=(7) AND [_DatabaseTesta].[dbo].[Review].[ReviewStatusModified] as [R].[Re 3           4           3           Stream Aggregate              
       |--Sort(ORDER BY:([Expr1015] ASC, [Expr1014] ASC))                                                                                                                                                                                                        3           5           4           Sort                          
            |--Compute Scalar(DEFINE:([Expr1014]=CASE WHEN [@Group1]=(1) THEN CONVERT(varchar(100),[_DatabaseTesta].[dbo].[Review].[LocationId] as [R].[LocationId],0) ELSE CASE WHEN [@Group1]=(10) THEN CONVERT(varchar(100),[_DatabaseTesta].[dbo].[Review].[ 3           6           5           Compute Scalar                
                 |--Filter(WHERE:(([_DatabaseTesta].[dbo].[ReviewSpecialist].[SupervisorId]=CONVERT_IMPLICIT(uniqueidentifier,[@SupervisorID],0) AND [@SupervisorID] IS NOT NULL OR [@SupervisorID] IS NULL) AND ([_DatabaseTesta].[dbo].[ReviewSpecialist].[Spe 3           7           6           Filter                        
                      |--Nested Loops(Left Outer Join, OUTER REFERENCES:([R].[Id]))                                                                                                                                                                              3           8           7           Nested Loops                  
                           |--Nested Loops(Inner Join, OUTER REFERENCES:([U].[locationID]))                                                                                                                                                                      3           9           8           Nested Loops                  
                           |    |--Nested Loops(Inner Join, WHERE:([_DatabaseTesta].[dbo].[Review].[LocationId] as [R].[LocationId]=[_DatabaseTesta].[dbo].[_SOC_USER].[locationID] as [U].[locationID]))                                                        3           10          9           Nested Loops                  
                           |    |    |--Sort(ORDER BY:([R].[Id] ASC))                                                                                                                                                                                            3           11          10          Sort                          
                           |    |    |    |--Compute Scalar(DEFINE:([Expr1047]=CASE WHEN [_DatabaseTesta].[dbo].[Review].[ReviewStatusId] as [R].[ReviewStatusId]=(16) OR [_DatabaseTesta].[dbo].[Review].[ReviewStatusId] as [R].[ReviewStatusId]=(14) OR [Qual 3           12          11          Compute Scalar                
                           |    |    |         |--Nested Loops(Inner Join, OUTER REFERENCES:([R].[Id], [Expr1056]) WITH UNORDERED PREFETCH)                                                                                                                      3           13          12          Nested Loops                  
                           |    |    |              |--Hash Match(Inner Join, HASH:([R].[Id])=([R].[Id]))                                                                                                                                                        3           16          13          Hash Match                    
                           |    |    |              |    |--Index Scan(OBJECT:([_DatabaseTesta].[dbo].[Review].[idxReview_Status_Loc] AS [R]),  WHERE:(([_DatabaseTesta].[dbo].[Review].[LocationId] as [R].[LocationId]=[@LocationID] AND [@LocationID] IS NOT  3           17          16          Index Scan                    
                           |    |    |              |    |--Index Scan(OBJECT:([_DatabaseTesta].[dbo].[Review].[idx_Review_TenantID_QCType] AS [R]),  WHERE:([_DatabaseTesta].[dbo].[Review].[ChecklistTypeId] as [R].[ChecklistTypeId]=[@QCType] AND [@QCType]  3           18          16          Index Scan                    
                           |    |    |              |--Clustered Index Seek(OBJECT:([_DatabaseTesta].[dbo].[Review].[PK_Review] AS [R]), SEEK:([R].[Id]=[_DatabaseTesta].[dbo].[Review].[Id] as [R].[Id]),  WHERE:([_DatabaseTesta].[dbo].[Review].[SubLocation] 3           32          13          Clustered Index Seek          
                           |    |    |--Table Scan(OBJECT:([_DatabaseTesta].[dbo].[_SOC_USER] AS [U]))                                                                                                                                                           3           41          10          Table Scan                    
                           |    |--Clustered Index Seek(OBJECT:([_DatabaseTesta].[dbo].[Location].[PK_Location] AS [L]), SEEK:([L].[Id]=[_DatabaseTesta].[dbo].[_SOC_USER].[locationID] as [U].[locationID]),  WHERE:([_DatabaseTesta].[dbo].[Location].[IsActiv 3           43          9           Clustered Index Seek          
                           |--Nested Loops(Left Semi Join, WHERE:([_DatabaseTesta].[dbo].[ReviewSpecialist].[Id]=[Expr1008]))                                                                                                                                    3           44          8           Nested Loops                  
                                |--Nested Loops(Inner Join, OUTER REFERENCES:([_DatabaseTesta].[dbo].[ReviewSpecialist].[Id]))                                                                                                                                   3           45          44          Nested Loops                  
                                |    |--Index Seek(OBJECT:([_DatabaseTesta].[dbo].[ReviewSpecialist].[idxReviewSpecialist_ReviewID]), SEEK:([_DatabaseTesta].[dbo].[ReviewSpecialist].[ReviewId]=[_DatabaseTesta].[dbo].[Review].[Id] as [R].[Id]) ORDERED FORWA 3           46          45          Index Seek                    
                                |    |--Clustered Index Seek(OBJECT:([_DatabaseTesta].[dbo].[ReviewSpecialist].[PK_ReviewSpecialist]), SEEK:([_DatabaseTesta].[dbo].[ReviewSpecialist].[Id]=[_DatabaseTesta].[dbo].[ReviewSpecialist].[Id]) LOOKUP ORDERED FORWA 3           48          45          Clustered Index Seek          
                                |--Table Spool                                                                                                                                                                                                                   3           56          44          Table Spool                   
                                     |--Stream Aggregate(GROUP BY:([_DatabaseTesta].[dbo].[ReviewSpecialist].[ReviewId]) DEFINE:([Expr1008]=MIN([_DatabaseTesta].[dbo].[ReviewSpecialist].[Id])))                                                                3           57          56          Stream Aggregate              
                                          |--Sort(ORDER BY:([_DatabaseTesta].[dbo].[ReviewSpecialist].[ReviewId] ASC))                                                                                                                                           3           58          57          Sort                          
                                               |--Clustered Index Scan(OBJECT:([_DatabaseTesta].[dbo].[ReviewSpecialist].[PK_ReviewSpecialist]), WHERE:([_DatabaseTesta].[dbo].[ReviewSpecialist].[SpecialistId]=isnull(CONVERT_IMPLICIT(uniqueidentifier,[@Spec 3           59          58          Clustered Index Scan          
4

1 回答 1

1

在查询提示末尾添加 -option(recompile)

于 2013-04-15T13:16:06.860 回答