在SQL中的WHILE循环内运行UPDATE语句需要永远运行

时间:2017-03-23 11:58:23

标签: sql-server

我有一张包含大约1000万条记录的表格。我试图在1000个块中的while循环中更新此表,如下所示:

DECLARE @totalRecordCount INT
DECLARE @midCount INT
DECLARE @Chunksize INT

set @totalRecordCount = (SELECT COUNT(*) FROM Tabletemp) 
set @ChunkSize = CEILING(@totalRecordCount/1000)+1 -- Divide the total into 1000 chunks
set @midcount = @totalRecordcount
while @midcount > 0
BEGIN
    UPDATE top(@Chunksize) a 
    set a.x = b.x
    FROM TableTemp a
    INNER JOIN
    TableTemp2 b on a.id = b.id 
    WHERE a.x is Null

    SET @midCount=@@ROWCOUNT
END

我尝试在@@ ROWCOUNT之前添加一个select语句,看看到达那里需要多长时间,但查询会一直运行。当我使用相应的@Chunksize运行单个更新语句时,它最多运行13秒,但在循环中,它会一直运行。

我还用SELECT替换UPDATE以查看循环是否正常运行并且发现它运行良好。

为什么UPDATE永远无法运行,请帮忙!

3 个答案:

答案 0 :(得分:0)

每次循环最多可更新1000行。我不是100%肯定它会比1大更新更好(也许如果你包括DELAY):

如果在两个表中都在ID上创建索引,则可能不需要这样做。然而,这是实现您正在尝试的脚本。如果ID不是唯一的,那么肯定会遇到问题。

DECLARE @midCount INT = 1
DECLARE @Chunksize INT = 1000

WHILE @midcount > 0
BEGIN
  WITH CTE as
  (
    SELECT top(@ChunkSize) a.x, b.x newxvalue
    FROM TableTemp a
    JOIN TableTemp2 b
    ON a.id = b.id 
    WHERE a.x is Null and b.x is not null
  )
  UPDATE CTE SET x = newxvalue

  SET @midCount=@@ROWCOUNT
  --IF @midcount = @Chunksize WAITFOR DELAY '00:00:05' -- 5 sec delay
END

答案 1 :(得分:0)

我认为你没有a.x的索引

如果有一次大的更新,可以通过一次全表扫描来完成。

如果是块,您将在每次迭代中扫描所有已经更新的行(因为扫描中的行顺序不会更改)。例如。将使用大约NUMBER_OF_CHUNKS个全表扫描进行更新

答案 2 :(得分:0)

以块的形式更新似乎需要更长的时间,而不是在没有块的情况下进行更新时,它的运行速度要快得多。同时添加索引也有帮助。

在几个循环不确定出于什么原因后,块中的更新会被卡住。