表更新性能随行计数减少

时间:2018-06-07 16:09:40

标签: sql-server tsql

我正在编写一个查询来更新一个大表(超过60亿行)。遗憾的是,由于磁盘存储限制,插入新表不是一种选择。

我已经完成了性能测试,问题的答案都是here,第二个答案似乎是最快的选择。

我已经使用1,2,3,5和1000万行测试了查询性能。我添加到更新的行越多,性能就会大幅降低。

以下是我的更新查询示例:

DECLARE @Rows INT, @BatchSize INT;
SET @BatchSize = 4500;

SET @Rows = @BatchSize; 

WHILE (@Rows = @BatchSize)
BEGIN
    UPDATE TOP (@BatchSize) [dbo].[TestTable]
    SET MyID1 = MyID2
    FROM  [dbo].[TestTable]
    WHERE MyID1 <> MyID2

    SET @Rows = @@ROWCOUNT;
END

这是完成时间和每秒更新行数:

  • 1百万行:43秒完成,23255行/秒
  • 2百万行:完成168秒,11904行/秒
  • 3百万行:366秒完成,8196行/秒
  • 500万行:1098秒完成,4553行/秒
  • 1000万行:完成3922秒,2549行/秒

我认为我应该能够平均每秒的行数并估计完成时间,但完成的时间似乎呈指数级增长。例如,将完成500万行的时间加倍应该在2200秒左右完成,但它需要3922秒。

多次测试会返回类似的结果,因此我不认为我正在处理争用问题。另外,这是在未使用的测试服务器上。我在这里缺少什么,如何准确估计完成此更新的时间?

1 个答案:

答案 0 :(得分:0)

我能够提出有效的更新查询。下面的查询在15秒内更新了500万行,在30秒内更新了1000万行。

我在BatchKey列上创建了一个聚簇索引,它是一个整数标识列。然后编写查询以基于MinMax BatchKey循环遍历行。

DECLARE @MaxKey BIGINT, @MinKey BIGINT, @iMax BIGINT, @iMin BIGINT

SELECT 
    @MinKey = MIN(BatchKey), 
    @MaxKey = MAX(BatchKey)
FROM dbo.TestTable

SET @iMin = @MinKey         -- starting minimum key
SET @iMax = @MinKey + 4500  -- starting maximum key for batch

WHILE (@iMin < @MaxKey) 
BEGIN
    UPDATE dbo.TestTable
    SET MyID1 = MyID2
    FROM  dbo.TestTable
    WHERE BatchKey >= @iMin
    AND BatchKey <= @iMax

    SET @iMin = @iMax + 1       -- get next minimum key
    SET @iMax = @iMin + 4500    -- get next maximum batch key

END