我有一张包含大约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永远无法运行,请帮忙!
答案 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)
以块的形式更新似乎需要更长的时间,而不是在没有块的情况下进行更新时,它的运行速度要快得多。同时添加索引也有帮助。
在几个循环不确定出于什么原因后,块中的更新会被卡住。