我正在编写一个查询来更新一个大表(超过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
这是完成时间和每秒更新行数:
我认为我应该能够平均每秒的行数并估计完成时间,但完成的时间似乎呈指数级增长。例如,将完成500万行的时间加倍应该在2200秒左右完成,但它需要3922秒。
多次测试会返回类似的结果,因此我不认为我正在处理争用问题。另外,这是在未使用的测试服务器上。我在这里缺少什么,如何准确估计完成此更新的时间?
答案 0 :(得分:0)
我能够提出有效的更新查询。下面的查询在15秒内更新了500万行,在30秒内更新了1000万行。
我在BatchKey
列上创建了一个聚簇索引,它是一个整数标识列。然后编写查询以基于Min
和Max
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