1回のトランザクションで10kレコードの制限を入れるために、SQL Serverのテーブルを更新する最も効果的な方法は何ですか?バッチ内でのSqlの更新
私はトップを読んで、ROWCOUNT
アプローチをwhileループで追加しています。そのうちどちらが効果的ですか?あるいは、別の効果的な方法を知っている場合は、共有してください。ありがとうございました。ここで
1回のトランザクションで10kレコードの制限を入れるために、SQL Serverのテーブルを更新する最も効果的な方法は何ですか?バッチ内でのSqlの更新
私はトップを読んで、ROWCOUNT
アプローチをwhileループで追加しています。そのうちどちらが効果的ですか?あるいは、別の効果的な方法を知っている場合は、共有してください。ありがとうございました。ここで
-- prepare test data
use tempdb
drop table dbo.t;
create table dbo.t (a int identity, b int)
go
insert into dbo.t (b)
values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11);
go
-- assume we do 3 records per time, put 10000 here if you wnat 10K records
-- also the update is just to update column [b] to [b] * 2, here is the code
declare @N int = 3; -- do a batch of @N records
declare @i int = 0, @max_loop int;
select @max_loop = count(*)/@N from dbo.t
-- the first batch may include records <= @N-1 and the last batch may include records <= @N
while (@i <= @max_loop)
begin
; with c as (
select rnk=ROW_NUMBER() over (order by a)/@N, a, b from dbo.t
)
update c set b = b*2 -- doule b
where rnk = @i;
set @i = @i + 1;
end
go
-- check the result
select * from dbo.t
を使用せずに1個の潜在的なアプローチは、あなたが以下のアプローチを試すことができます:組織と作りの全従業員のための
WHILE (1=1)
BEGIN
BEGIN TRANSACTION
UPDATE TOP (10000) XXX
SET XXX.YYY = <ValueToUpdate>
FROM XXX -- Update 10000 nonupdated rows
WHERE <condition> -- make sure that condition makes sure that it does not become infinite loop
IF @@ROWCOUNT = 0
BEGIN
COMMIT TRANSACTION
BREAK
END
COMMIT TRANSACTION
END
EDIT
更新それが完全なループにならないことを確かめてください。ここでは、従業員レコードのmodifiedDateを更新しています。
DECLARE @updatedids table(id int)
WHILE (1=1)
BEGIN
BEGIN TRANSACTION
UPDATE TOP(10000) a
SET a.ModifiedDate = GETDATE()
OUTPUT inserted.BusinessEntityID INTO @updatedids
FROM HumanResources.Employee a
LEFT JOIN @updatedids u
ON a.BusinessEntityID = u.id
WHERE u.id IS NULL
-- Update 10000 nonupdated rows
IF @@ROWCOUNT = 0
BEGIN
COMMIT TRANSACTION
BREAK
END
COMMIT TRANSACTION
END
同じ10000行が連続的に更新される可能性があるため、デッドループになります。 (私がテストしたSQLサーバでは少なくとも) – jyao
WHERE句が見つかりませんでした。ごめんなさい。私はコードを更新しました。私は主にロジックに集中しました。 –
テーブルのGENERIC更新では、既に更新された条件を除外するための有効な条件が存在しないことがあります。たとえば、[emploee_id]と[salary]という2つの列を持つ表があり、すべての人に10%の増加をさせたいとしましょう。この表に100万行があると仮定すると、私たちはこのテーブルを10K /チャンクアップデートで更新したいのですが、どうすればよいwhere節を思いつくことができますか? – jyao
現時点ではどのスクリプトを使用していますか? – mfredy
ROWCOUNTを使用して、UPDATE文で行を更新する方法を制御しないでください。これに対する使用は廃止され、将来的には機能しなくなります。 https://msdn.microsoft.com/en-us/library/ms188774.aspx –
一度に10,000行ごと、または一番上の10,000行だけを更新する予定ですか? – ZLK