SQL Server中的游标花费太多时间处理3500万条记录

时间:2019-03-25 09:00:05

标签: sql-server performance tsql database-cursor

我已经在存储过程中创建了一个游标,我的select语句结果大约有3500万条记录。

我正在获取游标的每个值并执行存储过程,依次,下一个存储过程正在调用另一个具有一些插入语句的存储过程。

该查询需要2天以上的时间才能完成其执行,每次游标行花费0.7秒,即有3500万行。

查询如下:

-- Created a cursor to read over data
DECLARE testCursor CURSOR FAST_FORWARD LOCAL FOR
    SELECT 
        StartTime, EndTime, [datares], Id, address,
        c.RCount, c.SCount 
    FROM 
        ConData c

-- Opening the cursor and fetching the first Condata
OPEN testCursor

FETCH NEXT FROM testCursor INTO
    @startTime, @endTime, @datares, @Id, @address, @rCount, @sCount

WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC InsertOrUpdateConData @startTime, @endTime, @datares, @Id, @address, @rCount, @sCount

    UPDATE DataRec
    SET EndTime = @endTime
    WHERE Id = @pId AND Type = 'ConData' AND Int1 = @Id

    -- Fetch the next conversation
    FETCH NEXT FROM testCursor INTO
        @startTime, @endTime, @datares, @Id, @address, @rCount, @sCount
END

CLOSE testCursor 
DEALLOCATE testCursor 

如何减少执行该查询所需的时间?

1 个答案:

答案 0 :(得分:0)

您应该以一种基于集合的方式编写代码:

  1. 移动此语句SELECT StartTime,EndTime,[datares],Id,address, c.RCount,c.SCount FROM ConData c您的InsertOrUpdateConData存储过程
  2. 然后根据UPDATE使用SELECT StartTime,EndTime,[datares],Id,address, c.RCount,c.SCount FROM ConData c

这不是基于集合的解决方案,而是尝试使用WHILE语句:

DECLARE @YourID INT = (SELECT MIN(Id) FROM ConData); -- First ID
DECLARE @StartTime VARCHAR(200);
DECLARE @EndTime VARCHAR(200);
DECLARE @datares VARCHAR(200);
DECLARE @address VARCHAR(200);
DECLARE @RCount INT;
DECLARE @SCount INT;


-- Iterate over all ID's
WHILE @YourID IS NOT NULL
BEGIN  

  -- Get data based on ID
 SELECT @StartTime = StartTime,
        @EndTime = EndTime,
        @datares = [datares],
        @address = address,
        @RCount = c.RCount,
        @SCount = c.SCount 
 FROM ConData c.ID = @YourID;

  -- call your sproc
  EXEC InsertOrUpdateConData @startTime, @endTime, @datares, @Id, @address,@rCount, @sCount

  -- Get next Id
  SELECT @YourID = MIN(id)
    FROM ConData
    WHERE id > @YourID

END