因此,我有一个存储过程,需要定期更新一个大型表,其中包含大约7000万条记录。我通常总是遵循循环更新的标准来避免锁定我的其他大型表,并且通常我没有看到性能影响太大。循环SQL Server更新语句的性能不佳
问题: 当我使用循环相比,没有循环逻辑的原始运行时我看到了10倍或20倍我的执行时间增加。
例如:
如果我运行下面的查询我会在大约150分钟更新一次300万条记录。
UPDATE [db1].[dbo].[Preferences]
SET LastUpdate = Getdate()
WHERE
LastUpdate >= CAST(CONVERT(Varchar(10), DATEADD(day,-1,GETDATE()), 110) as DateTime)
AND
LastUpdate < CAST(CONVERT(Varchar(10), GETDATE(), 110) as DateTime)
AND (@PreferenceID is null or @PreferenceID = PreferenceID)
这是我的常规更新语句,没有循环机制。基本上,参数@PreferenceID或者提供了一个ID或留空。根据它,它将更新所有lastUpdate的当前日期或只更新一个preferenceID。在我的测试用例中,我使用了1个preferenceID,因此@PreferenceID正在被填充。
所以当我在这个语句中加入循环时,它花了1.5分钟到20分钟。
下面是循环语句:
BEGIN
SET ROWCOUNT 10000
UPDATE [DB1].[dbo].[Preferences]
SET LastUpdate = Getdate()
WHERE
LastUpdate >= CAST(CONVERT(Varchar(10), DATEADD(day,-1,GETDATE()), 110) as DateTime)
AND
LastUpdate < CAST(CONVERT(Varchar(10), GETDATE(), 110) as DateTime)
AND (@PreferenceID is null or @PreferenceID = PreferenceID)
WHILE @@ROWCOUNT > 0
UPDATE [DB1].[dbo].[Preferences]
SET LastUpdate = Getdate()
WHERE
LastUpdate >= CAST(CONVERT(Varchar(10), DATEADD(day,-1,GETDATE()), 110) as DateTime)
AND
LastUpdate < CAST(CONVERT(Varchar(10), GETDATE(), 110) as DateTime)
AND (@PreferenceID is null or @PreferenceID = PreferenceID)
SET ROWCOUNT 0
END
所以我的核心问题是为什么我的执行时间增长这么多只是做的10K的循环记录时间?我可以发布有关表结构的更详细的信息,但我不确定这是否是一个坚定的规则,与只进行一次完整批量更新相比,执行循环更新的性能会受到影响。
在此先感谢任何人可以提供的建议。
你在每一个更新做检查点? –
为什么不把getdate()保存到一个变量中并使用它呢? –
您是否尝试过增加50000或100000批量? –