2014-09-18 4 views
-3

6500 검사기에 대해 일부 통계를 실행하도록 SQL 쿼리를 설계했지만 너무 오래 걸립니다. sql에는 다른 많은 선택 쿼리가 있지만 실행 중입니다. 그러나 "TotalVisitsWithAtLeastOneReport"선택이 매우 느리게 실행됩니다.쿼리가 매우 느리게 실행 중입니다.

요건 :

Inspectors: InspectorID 
InspectionScope: ScopeID, InspectorID (FK) 
Visits: VisitID, VisitDate ScopeID (FK) 
VisitsDoc: DocID, DocType, VisitID (FK) 

SQL :

방문 문서 (1 또는 2 또는 13)에 업로드 한 각 검사

테이블에 대한 방문

  • 번호
    DECLARE 
         @DateFrom90 date, @DateTo date, @DateFrom180 date, @DateFrom date; 
    
    SELECT @DateTo  = CAST(GETDATE() AS DATE) 
         ,@DateFrom90 = CAST(GETDATE() - 90 AS DATE) 
         ,@DateFrom180 = CAST(GETDATE() - 180 AS DATE) 
    
    
    
    DECLARE @Inspectors TABLE (
         InspectorID int, 
         InspectorGrade int, 
         DateFrom date, 
         DateTo date 
         ); 
    
    insert into @inspectors (
         InspectorID , 
         InspectorGrade, 
         DateFrom , 
         DateTo 
         ) 
    
    select tmp.InspectorID , tmp.InspectorGrade 
         ,case when tmp.VisitWithReport = 0 then @DateFrom180 else @DateFrom90 end StartDate 
         ,@DateTo EndDate 
    from 
    (
        select i.InspectorID , i.InspectorGrade 
          ,VisitWithReport = (select COUNT(v.visitid) 
               from visits v 
               inner join InspectionScope s on s.ScopeID = v.ScopeID 
               where v.ReportStandard not in (0,9) and v.VisitType = 1 
               and v.VisitDate BETWEEN @DateFrom90 and @DateTo 
               and s.InspectorID = i.InspectorID)  
        from inspectors i 
    ) tmp; 
    
    
    SELECT i.InspectorID , i.InspectorGrade 
         ,TotalVisitsWithAtLeastOneReport = (select COUNT(distinct v.visitID) 
                  from Visits v 
                  inner join InspectionScope s on s.ScopeID = v.ScopeID 
                  inner join VisitDocs vd on vd.VisitID = v.VisitID 
                  where vd.DocType IN (1,2,13) and s.InspectorID = i.InspectorID 
                  and v.VisitDate BETWEEN i.DateFrom and i.DateTo 
    
                 ) 
    from @Inspectors i 
    

    select i.InspectorID , i.InspectorGrade 
          ,VisitWithReport = (select COUNT(v.visitid) 
               from visits v 
               inner join InspectionScope s 
               on s.ScopeID = v.ScopeID 
               where v.ReportStandard not in (0,9) and v.VisitType = 1 
               and v.VisitDate BETWEEN @DateFrom90 and @DateTo 
               and s.InspectorID = i.InspectorID) 
    from inspectors i  
    

    을 수행하지 않는

    enter image description here

+0

좋은 검색어입니다. 너는 더 나은 선택권이있다. – johnny

+0

커서가 느리기 때문에이 속도가 느립니다. –

+1

'COUNT (v.visitid)'와'COUNT (distinct v.visitID) '에있는 해당 subselect는 전체 스크립트에 대해 취해진 실행 계획을 (그림) 포함시켜야한다는 것을 의미합니다. – DrCopyPaste

답변

0

쿼리 튜닝 어드바이저와 이후에 내 sql을 확인했습니다. 다음과 같은 비 클러스터 인덱스를 생성하면 SQL 스크립트는 실행하는 데 2 ​​~ 3 초 밖에 걸리지 않습니다. 이것을 더 테스트 할 것이고, 라이브로 구현되기 전에 시스템의 다른 부분에 영향을 미치지 않을지를 볼 것입니다.

CREATE NONCLUSTERED INDEX [DocType_VisitID] ON [dbo].[VisitDocs] 
(
[DocType] ASC, 
[VisitID] ASC 
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY] 
0

브레이크를 아래로 볼이 시도 - 당신이 훨씬 더 가능성

select i.InspectorID, i.InspectorGrade 
    , COUNT(v.visitid) as VisitWithReport 
    from inspectors i 
    join InspectionScope s 
    on s.InspectorID = i.InspectorID   
    join visits v 
    on v.ScopeID = s.ScopeID  
    and v.ReportStandard not in (0,9) 
    and v.VisitType = 1 
    and v.VisitDate BETWEEN @DateFrom90 and @DateTo 
group by i.InspectorID, i.InspectorGrade 


SELECT i.InspectorID , i.InspectorGrade 
     ,TotalVisitsWithAtLeastOneReport = (select COUNT(distinct v.visitID) 
              from Visits v 
              inner join InspectionScope s on s.ScopeID = v.ScopeID 
              inner join VisitDocs vd on vd.VisitID = v.VisitID 
              where vd.DocType IN (1,2,13) and s.InspectorID = i.InspectorID 
              and v.VisitDate BETWEEN i.DateFrom and i.DateTo 

             ) 
from @Inspectors i 

SELECT i.InspectorID , i.InspectorGrade 
     , COUNT(distinct v.visitID) as TotalVisitsWithAtLeastOneReport 
    from @Inspectors i 
    join InspectionScope s 
     on s.InspectorID = i.InspectorID 
    join Visits v 
     on s.ScopeID = v.ScopeID 
    join VisitDocs vd 
     on vd.VisitID = v.VisitID 
     and vd.DocType IN (1,2,13) 
     and v.VisitDate BETWEEN i.DateFrom and i.DateTo 
    group by i.InspectorID , i.InspectorGrade 
을 시도 스마트 얻을에게 쿼리 최적화를 제공
+0

쿼리가 문제를 일으키고 있습니다. – user1263981

+0

왜이 투표 결과가 아래 표를 얻었습니까? – Paparazzi

+0

나는 왜 투표를 했습니까? – user1263981

관련 문제