3

DB に 2 つのテーブルがあり、1 つにはクライアントに関するデータ (Clients と呼ばれる) が含まれ、もう 1 つのテーブルには clientID、Guid、AddedTime、および IsValid (ClientsToUpdate と呼ばれる) が含まれます。

ClientID はクライアント テーブルに関連し、Guid は一意の識別子、AddedTime はレコードがテーブルに追加された時刻、IsValid はこの ClientID が更新されたかどうかを示すビットです。

私がやりたいことは、ID が ClientsToUpdate にあるすべてのクライアントを更新することです。問題は、ClientsToUpdate テーブルに 80,000 を超えるレコードが含まれており、デッドロックが発生していることです。

私にできることは、while ループなどを使用して、一度に 2000 のクライアントを更新することです。

私のストアドプロシージャは次のようになります。

UPDATE client SET LastLogin=GETDATE() 
FROM Clients client
JOIN ClientsToUpdate ctu ON client.ID = ctu.ClientID;

どうすればそれを行うことができますか?

4

2 に答える 2

4
declare @done table (ClientID int primary key)
while 1=1
    begin

    update  top (2000) c
    set     lastlogin = getdate()
    output  deleted.id into @done
    from    Clients c
    join    ClientsToUpdate ctu
    on      c.id = ctu.ClientID
    where   not exists
            (
            select  *
            from    @done d
            where   d.ClientID = ctu.ClientID
            )

    if @@rowcount = 0
        break
    end

SQL Fiddle の例。

于 2012-10-28T08:43:30.077 に答える
0

デッドロックが発生した場合、チャンクで更新するとエラーが減る可能性がありますが(トランザクションを注意深く管理し、チャンクの更新をコミットすると想定)、デッドロックの原因は解決されません。私見では、ロックの問題を調査し、デッドロックが発生する理由を見つける必要があります

于 2012-10-28T10:08:41.173 に答える