更新sql server中的大量行
Posted
技术标签:
【中文标题】更新sql server中的大量行【英文标题】:Update Large Number of rows in sql server 【发布时间】:2013-11-08 20:16:15 【问题描述】:我正在尝试更新大约 90,000 行的表中的列。有没有优化的方法来更新表格?
我添加了必要的索引.. 这样就不会发生表扫描/查找。但仍然需要很长时间才能运行(1 小时)。
我的场景:
DECLARE @ParentID NVARCHAR(100),
@Con_ERID INT
DECLARE @MaxCount INT,
@MinCount INT,
@Id INT
SELECT @MaxCount = MAX(Id) from [dbo].[ParentIDStaging] where Type='grid'
SET @MinCount = 1
WHILE @MinCount <= @MaxCount
BEGIN
SELECT @Id = ConID FROM [dbo].[ParentIDStaging] WHERE Id = @MinCount and Type = 'grid'
IF @Id IS NOT NULL
BEGIN
SELECT @Con_ERID = ErId FROM Context (NOLOCK) Where ConId = @Id
SELECT @ParentID = Identifier FROM Recording (NOLOCK) where ErId = @Con_ERID
BEGIN TRAN
UPDATE [ParentIDStaging] WITH (ROWLOCK)
SET [ParentID] = @ParentID
WHERE ContentType = 'grid'
AND ConID = @Id
COMMIT
END
SET @MinCount = @MinCount + 1
END
【问题讨论】:
这是因为您一次更新一条记录并使用显式锁定/事务。 正如其他人所说(我将重复)循环、单独的事务等都会减慢您的速度。我也很好奇 ParentIDStaging.ParentID 是否涉及clustered index
的键中的任何位置。如果是这样,则每次更新都会(几乎可以肯定)导致 ParentIDStaging 中的级联更新,因为表中的行(即使一次只有一个叶节点)被重新排列。如果是这种情况,您最好在循环之前/之后删除并重新创建 clustered index
。
再次 - 我不知道你的数据/模式/流程 - 但我也很好奇 ParentIDStaging.ParentID 是否总是错误的(并且需要更新)。我以前见过这样的循环,他们更新表中的所有记录,当时只有少数新行具有“错误”值 - 并且简单地将 and ParentID<>@ParentID
添加到 where
对性能产生了深远的影响.
嗨.. ParentID 最初包含 NULL 值.. 我用其他表中的值更新 parentid 列.. 这个 parentid 列需要填充实际值(在 qry 中的更新 stmt ) 而且 ParentIDStaging 表上没有聚集索引..我只在表上创建了非聚集索引,所以不会发生表扫描......但性能仍然很差..
您是否检查过每个select
是否被覆盖?为什么要将更新分解为单独的事务?所有这些都会产生影响。我会检查索引(因此每个查询/连接都被覆盖),然后查看基于集合的更新 - 而不是循环。
【参考方案1】:
循环很慢。尝试在一次更新中使用连接包含相关的其他表。您的查询可能会这样写(不知道您的实际架构):
UPDATE PS
SET PS.ParentID = Recording.Identifier
FROM ParetnIDStaging PS
JOIN Context on (Context.ConId = PS.ConId)
JOIN Recording on (Recording.ErId = Context.ErId)
WHERE ...
【讨论】:
【参考方案2】:这是因为您一次循环和更新一条记录并使用显式锁/事务。
在不知道你的底层结构的情况下 - 我敢打赌你可以通过选择更新来做你正在尝试的事情。
【讨论】:
【参考方案3】:UPDATE ParentIDStaging
SET parentIdStaging.ParentID=recording.Identifier
from ParentIDStaging
join Context on context.ConId = ParentIDStaging.ConId
join recording on contect.erid=recording.erId
WHERE parentIdStaging.ContentType = 'grid'
AND parentidStaging.Type='grid'
【讨论】:
以上是关于更新sql server中的大量行的主要内容,如果未能解决你的问题,请参考以下文章