【发布时间】: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是否被覆盖?为什么要将更新分解为单独的事务?所有这些都会产生影响。我会检查索引(因此每个查询/连接都被覆盖),然后查看基于集合的更新 - 而不是循环。
标签: sql-server tsql sql-update query-performance bulkupdate