3

是否有可能或完全推荐运行一个更新查询,一次更新近 10 万条记录?

如果是这样,我该怎么做?我正在尝试将一个数组传递给我的存储过程,但它似乎不起作用,这是我的 SP:

CREATE PROCEDURE [dbo].[UpdateAllClients]
    @ClientIDs varchar(max)
AS
BEGIN
    DECLARE @vSQL varchar(max)
    SET @vSQL = 'UPDATE Clients SET LastUpdate=GETDATE() WHERE ID IN (' + @ClientIDs + ')';
    EXEC(@vSQL);
END

我不知道什么不起作用,但它只是没有更新相关查询。

任何人?

4

7 回答 7

5

UPDATE正在阅读您的(@ClientIDs作为逗号分隔值)作为一个整体。为了进一步说明,您正在这样做。

假设@ClientIDs = 1,2,3,4,5

你的UPDATE命令是这样解释的

UPDATE Clients SET LastUpdate=GETDATE() WHERE ID IN ('1,2,3,4,5')';

并不是

UPDATE Clients SET LastUpdate=GETDATE() WHERE ID IN (1,2,3,4,5)';

对您的问题的一个建议是在您的UPDATE示例上使用子查询

UPDATE Clients 
   SET LastUpdate = GETDATE() 
WHERE ID IN
    (
       SELECT ID
       FROM tableName
       -- where condtion
    )

希望这是有道理的。

希望这可以帮助

于 2012-09-07T07:50:11.700 回答
3

需要注意的一些注意事项。

像这样的大更新会锁定目标表。如果操作影响 > 5000 行,则单个行锁将提升为表锁,这将阻塞其他进程。如果这可能会导致您的场景出现问题,请记住这一点。请参阅:锁升级

像这样更新大量行,我考虑的一种方法是(基本):

  1. 将 100K Id 批量插入临时表(例如,来自 .NET,使用 SqlBulkCopy)
  2. 更新目标表,使用连接到上面的临时表
  3. 删除临时表

这为控制过程提供了更多空间,但将工作负载分成块并一次执行 x 行。

于 2012-09-07T07:59:18.373 回答
0

你用的是什么版本的sql server?如果是 2005+,我建议使用 TVP(表值参数 - http://msdn.microsoft.com/en-us/library/bb510489.aspx)。数据传输会更快(而不是构建一个巨大的字符串),并且您的查询看起来会更好:

update c
set lastupdate=getdate()
from clients c
join @mytvp t on c.Id = t.Id
于 2012-09-07T08:57:56.997 回答
0

每个 SQL 语句本身就是一个transaction语句。这意味着 sql server 将为所有这些数百万行获取锁。它确实会降低表的性能。所以你真的不倾向于更新一个有数百万行的表,这会损害性能。所以解决方法是在 DML 操作之前设置行

set rowcount=100
UPDATE Clients SET LastUpdate=GETDATE()
WHERE ID IN ('1,2,3,4,5')';
set rowcount=0

或者从 SQL server 2008 你可以参数化 Top 关键字

Declare @value int
set @value=100000 
again:
UPDATE top (@value) Clients SET LastUpdate=GETDATE()
WHERE ID IN ('1,2,3,4,5')';
if @@rowcount!=0  goto again 

查看上述查询的速度,然后调整和更改变量的值。您需要按照上述答案中的建议为较小的单位中断任务

于 2012-09-07T09:24:47.207 回答
0

如果您提供数组,则传递给“IN”的项目数量是有限制的。

因此,如果您只想更新整个表,请跳过 IN 条件。

如果没有在 IN 中指定 SQL。那应该做的工作

于 2012-09-07T07:53:21.547 回答
0

数据库很可能会拒绝该 SQL 语句,因为它太长了。

当您需要一次更新这么多记录时,您的数据库架构可能不合适。也许 LastUpdate 数据不应该为每个客户端单独存储,而是全局只存储一次,或者对于一组恒定的客户端只存储一次?

但是,如果不了解全局,就很难推荐一个好的行动方案。

于 2012-09-07T07:53:58.387 回答
0

方法一:

  1. 使用分隔符 ',' 拆分 @clientids
  2. 放入数组并遍历该数组
  3. 更新每个 id 的客户端表。

或者

方法二:

不要将@clientids 作为varchar2,而是按照以下步骤操作

  1. 为 ids 创建对象类型表并使用连接。
  2. 为了加快处理速度,您还可以在 clientid 上创建索引。
于 2013-10-30T11:10:51.803 回答