【问题标题】:Update Large Number of rows in sql server更新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&lt;&gt;@ParentID 添加到 where 对性能产生了深远的影响.
  • 嗨.. ParentID 最初包含 NULL 值.. 我用其他表中的值更新 parentid 列.. 这个 parentid 列需要填充实际值(在 qry 中的更新 stmt ) 而且 ParentIDStaging 表上没有聚集索引..我只在表上创建了非聚集索引,所以不会发生表扫描......但性能仍然很差..
  • 您是否检查过每个select 是否被覆盖?为什么要将更新分解为单独的事务?所有这些都会产生影响。我会检查索引(因此每个查询/连接都被覆盖),然后查看基于集合的更新 - 而不是循环。

标签: sql-server tsql sql-update query-performance bulkupdate


【解决方案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'
      

      【讨论】:

        猜你喜欢
        • 2014-08-01
        • 2016-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-29
        • 2015-11-26
        • 2012-05-05
        • 1970-01-01
        相关资源
        最近更新 更多