查询运行速度很慢

时间:2014-09-18 16:06:13

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

我设计了一个sql查询来对6500个检查员运行一些统计数据,但这花费的时间太长了。在sql中有许多其他选择查询,但它们运行正常,但“TotalVisitsWithAtLeastOneReport”选择运行速度非常慢。

要求:

  • 访问上传文件(1或2或13)的每位检查员的访问次数

表:

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

SQL:

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 

enter image description here

2 个答案:

答案 0 :(得分:0)

将其分解并查看其未执行的位置

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    

试试这个 - 你给查询优化器提供了更多智能的机会

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

答案 1 :(得分:0)

我已经在查询调优顾问程序中检查了我的sql,并且在创建了以下非集群索引之后,sql脚本现在只需要执行两到三秒。我将对此进行更多测试,看看它是否会在实时实现之前影响系统的其他部分。

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]