是否可以或建议运行一个更新查询,一次更新近100k条记录?
如果是这样,我该怎么做?我试图将一个数组传递给我的存储过程,但它似乎不起作用,这是我的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
我不知道什么不起作用,但它只是没有更新相关的查询。
任何?
答案 0 :(得分: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
)
希望这是有道理的。
答案 1 :(得分:3)
需要注意的一些注意事项。
像这样的大更新可以锁定目标表。如果> 5000行受操作影响,单个行锁将被提升为表锁,这将阻止其他进程。值得注意的是,如果这可能会导致您的方案出现问题。请参阅:Lock Escalation
要像这样更新大量行,我要考虑的方法是(基本的):
这为控制流程提供了更多空间,但是将工作负载分成多个块并一次x行。
答案 2 :(得分:0)
如果您提供数组,则传递给“IN”的项目数量有限制。
因此,如果您只想更新整个表格,请跳过IN条件。
如果没有在IN中指定SQL。那应该做的工作
答案 3 :(得分:0)
数据库很可能会拒绝该SQL语句,因为它太长了。
当您需要一次更新这么多记录时,那么您的数据库架构可能不合适。也许LastUpdate数据不应该为每个客户端单独存储,而是全局只存储一次,或者对于一组常量客户端只能存储一次?
但如果不了解整体情况,很难推荐一个好的行动方案。
答案 4 :(得分: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
答案 5 :(得分:0)
每个SQL语句本身都是transaction
语句。这意味着sql server将为所有这些百万行获取锁。它实际上可以降低表的性能。所以你真的不倾向于更新一个有数百万行的表,这会损害性能。所以解决方法是在DML操作之前设置rowcount
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
查看上述查询的速度有多快,然后调整并更改变量的值。您需要按照上述答案的建议打破较小单位的任务
答案 6 :(得分:0)
方法1:
OR
方法2:
不要将@clientids作为varchar2,请按照以下步骤进行操作