我使用SQL Server 2014并需要在一个表中更新新添加的日期时间类型列。有两个相关的表(均具有> 30个百万条记录):如何优化运行数百万条记录的SQL Server合并语句
表A:
CategoryID, itemID, dataCreated, deleted, some other string properties.
此表包含不同datecreated
每个项目的倍数的记录。
表B:
CategoryID, itemID, LatestUpdatedDate (This is the new added column)
categoryID
两者和itemID
是在这个表的索引的一部分。
要更新tableB的的LatestUpdatedDate
从表一对匹配CategoryID
和ItemID
,我用下面的合并声明:
merge [dbo].[TableB] with(HOLDLOCK) as t
using
(
select CategoryID,itemID, max(DateCreated) as LatestUpdatedDate
from dbo.TableA
where TableA.Deleted = 0
group by CategoryID,itemID
) as s on t.CategoryID = s.CategoryID and t.itemID = s.itemID
when matched then
update
set t.LatestUpdatedDate = s.LatestUpdatedDate
when not matched then
insert (CategoryID, itemID, LatestUpdatedDate)
values (s.CategoryID, s.itemID)
鉴于数以百万计的在这两个表中的记录,我怎样才能优化这个脚本?还是有其他方式来更好的表现更好吗?
注意:这是一次性脚本并且数据库处于活动状态,将来会有一个触发器添加到tableA中,用于插入以更新tableB中的日期。
关键问题是:做的变化需要原子吗?有没有一段时间你可以独占锁定这个表?如果它不需要是原子的,那么我会把它分成独立的'update'和'insert'语句。那样你就把你的工作打破了一半。我之前被'合并'烧过,表现明智,所以现在我转而离开它。您还可以使用'set rowcount'技巧一次更新较小的批次,而不是一次性锁定整个表格。 –
我应该提到这是一个实时数据库,尽管我可以在晚上/周末期间运行脚本,但流量较少。合并之前你有什么样的性能问题?我不确定在这个关卡表上执行此操作需要多长时间。分钟,小时? – xingkong
合并时,性能与'when not matched'部分一致。你需要弄清楚这些变化是否需要原子化。也就是说:如果表格只是在几个小时内逐渐改变它,或者表格需要一次完全更新(为了一致性),那么可以。如果行y更新但不是行x,您的应用程序是否会中断?请注意,如果您在连接列上没有索引,这将会很慢(无论您以何种方式执行)。添加索引不是会改变应用程序的表格更改,您可以随后删除它们。 –