而在sql server中进行一些递归后,循环速度变慢
我有一个存储过程,它使用while循环迭代每个记录 然后做一些计算。存储过程具有以下逻辑: 将某些记录从旧\u表插入特定范围的新\u表 780万条记录。插入花了4分钟。 然后将金额大于100的记录复制到临时表中 37000项记录。 在临时表的id列上创建聚集索引。 启动while循环,以迭代temp表total 37000条记录中的每个id列。 对于每个迭代,在while循环中调用一个存储过程。 Sp的工作速度更快,最多可在5分钟内完成5000条记录 但在5000年之后,处理记录的时间有所延迟。延迟发生在处理每100条记录之后。这次延误有什么原因吗 存储过程的示例结构:而在sql server中进行一些递归后,循环速度变慢,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个存储过程,它使用while循环迭代每个记录 然后做一些计算。存储过程具有以下逻辑: 将某些记录从旧\u表插入特定范围的新\u表 780万条记录。插入花了4分钟。 然后将金额大于100的记录复制到临时表中 37000项记录。 在临时表的id列上创建聚集索引。 启动while循环,以迭代temp表total 37000条记录中的每个id列。 对于每个迭代,在while循环中调用一个存储过程。 Sp的工作速度更快,最多可在5分钟内完成5000条记录 但在5000年之后,处理记录的时间有所延迟。
use my_db
go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID('[dbo].[usp_datacopy]') IS NULL -- Check if SP Exists
EXEC('CREATE PROCEDURE [dbo].[usp_datacopy] AS SET NOCOUNT ON;') -- Create dummy/empty SP
GO
ALTER PROCEDURE [dbo].[usp_datacopy]
@Startdate datetime,
@Enddate datetime,
@Percent int
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
DECLARE @PerVal NUMERIC(10,2) = @percent /100.00,--Get the percent value for input.
@wkstartdate DateTime,
@wkenddate Datetime,
@OfficeID int,
@id int = 1,
@spcount int ,
@rdate datetime,
IF OBJECT_ID ('TEMPDB..#temptable') IS NOT NULL
DROP TABLE #temptable
INSERT INTO [dbo].[new_table]
( TimeID, OfficeID, dateval, rHour, Complexity,RowCountval)
SELECT TimeID + 364, OfficeID,dateadd(dd,364,dateval),rHour, Complexity , RowCountval,
FROM [dbo].[old_table] WITH (NOLOCK)
WHERE dateval BETWEEN @Startdate AND @Enddate
--select Day records with value > 100
SELECT ROW_NUMBER() over(order by timeid) id,TimeID, OfficeID, dateval, rHour, Complexity,RowCountval
INTO #temptable
FROM [dbo].[new_table] WITH (NOLOCK)
WHERE RDATE BETWEEN @wkstartdate AND @wkenddate
AND RowCountval > 100
CREATE CLUSTERED INDEX id_index on #temptable (id)
SELECT @spcount = COUNT (1) from #temptable
WHILE @id <= @spcount --37000 records
BEGIN
SELECT @OfficeID = officeid FROM #temptable WHERE id = @id
SELECT @rdate = dateval FROM #temptable WHERE id = @id
EXEC CalcPercentforEachRecord @rdate, @OfficeID, @PerVal
PRINT @ID
SELECT @id = @id + 1
SELECT @OfficeID = NULL
SELECT @rdate = NULL
END
IF @@ERROR = 0
BEGIN
COMMIT TRAN;
END
END TRY
BEGIN CATCH
SELECT @@ERROR AS ERROR,ERROR_MESSAGE() AS ErrorMessage,ERROR_LINE() AS ErrorLineNo
ROLLBACK TRAN;
END CATCH
SET NOCOUNT OFF;
END
请提供您的sp。。。我们没有水晶球:请添加您的执行计划。正如其他评论员所指出的,我们需要更多信息。也就是说,我至少要提到,尽管循环、游标或任何形式的每次记录处理在性能方面对我来说都是一个危险信号。准备从集合的角度思考,并相应地重构代码。有了更多的信息,我们可能会给你一个更简单的解决方案,也可能不会,但我的印象是,这个问题发生在冰层较薄的地区。我们可以得到CalcPercentforEachRecord的代码吗?您还可以将:SELECT OfficeID=OfficeID FROM tettable WHERE id=id选择rdate=dateval FROM tettable WHERE id=id替换为:SELECT OfficeID=OfficeID,rdate=dateval FROM tentable WHERE id=id这样,循环体中只有一个select语句,而不是创建自己的游标,您可以使用游标来迭代临时表,但请记住使用正确的设置,不仅仅是默认值——当然,最好通过彻底折磨row方法来摆脱row。