我设计了一个sql查询来对6500个检查员运行一些统计数据,但这花费的时间太长了。在sql中有许多其他选择查询,但它们运行正常,但“TotalVisitsWithAtLeastOneReport”选择运行速度非常慢。
要求:
表:
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
答案 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]