【发布时间】:2014-09-10 14:26:00
【问题描述】:
我设计了一个游标来针对 6500 名检查员运行一些统计信息,但花费的时间太长。游标中还有许多其他选择查询,但它们运行正常,但以下选择运行非常缓慢。没有光标选择查询运行得很好。
要求:
访问已上传文件的每个检查员的访问次数(1 次或 2 次或 13 次)
表格:
Inspectors: InspectorIDInspectionScope: ScopeID, InspectorID (FK)Visits: VisitID, VisitDate ScopeID (FK)VisitsDoc: DocID, DocType, VisitID (FK)
光标代码:
DECLARE
@curInspID int,
@DateFrom date, @DateTo date;
SELECT @DateTo = CAST(GETDATE() AS DATE)
,@DateFrom = CAST(GETDATE() - 90 AS DATE)
DECLARE
@InspectorID int,
@TotalVisits int;
DECLARE @Report TABLE (
InspectorID int,
TotalVisits int)
DECLARE curList CURSOR FOR
SELECT InspectorID FROM Inspectors ;
OPEN curList
FETCH NEXT FROM curList INTO @curInspID;
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
@curInspID = s.InspectorID
,@TotalVisits = 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 s.InspectorID = @curInspID and vd.DocType IN (1,2,13)
and v.VisitDate BETWEEN @DateFrom and @DateTo
group by s.InspectorID
INSERT INTO @Report VALUES(@curInspID,@TotalVisits);
FETCH NEXT FROM curList INTO @curInspID;
END
CLOSE curList
DEALLOCATE curList
SELECT * FROM @Report
以下查询在同一光标内运行正常
,@TotalVisitsWithReportScore = (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 @DateFrom and @DateTo
and s.InspectorID = @curInspID
)
,@TotalVisitsWith_ReportScore_RejectionFeedBack = (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.DiscrepancyType IN (2,5,6,7,8)
and v.VisitDate BETWEEN @DateFrom and @DateTo
and s.InspectorID = @curInspID
)
【问题讨论】:
-
我之前在使用游标运行查询时遇到过问题。如果您在中途取消它,它会将打开的游标保留在内存中。
-
请澄清一下 - 与相同参数选择但在光标外部进行比较的光标内的单个选择运行缓慢,还是此选择的总共 6500 次迭代比您预期的要慢?跨度>
-
@Andy,使用相同的参数选择外部光标不到 8 秒,但在光标内部需要超过 1 分钟。在同一个游标中还有许多其他选择查询运行良好,但为了使这个示例更短,我包含了一个运行缓慢的查询。我已经用其他几个运行正常的查询更新了我的问题
标签: sql sql-server-2008 tsql