2016-05-12 21 views
1

Ich denke, dies wird leichter zu erklären, indem ein paar Tabellen enthalten.Aktualisierung von Millionen von Datensätzen in SQL Server 2012

Tabelle A:

UserId  StoreId 
1   10 
2   20 
3   30 
4   40 

Tabelle B:

UserId  StoreId 
1   10 
1   20 
1   20 
2   20 
2   10 
2   10 
3   30 
3   40 
3   40 
4   40 
4   30 
4   30 

ich ein Skript benötigen, die in Tabelle 2 und aktualisieren den Laden gehen für diesen speziellen Benutzer die StoreId in Tabelle A entsprechen . Am Ende sollte ich sehen;

Tabelle B:

UserId  StoreId 
1   10 
1   10 
1   10 
2   20 
2   20 
2   20 
3   30 
3   30 
3   30 
4   40 
4   40 
4   40 

Also meine Frage ist, was ist der einfachste Weg, dies zu tun, wenn man bedenkt, dass Tabelle B hundert von Millionen von Zeilen in ihm hat, und Tabelle A hat etwa 20 Millionen Zeilen?

Vielen Dank im Voraus!

Antwort

5

Der beste Weg ist:

ALTER TABLE Table_B 
DROP COLUMN StoreId 

Jetzt bist du nicht mehr doppelte Daten zu speichern, und Sie können nur die StoreId von Table_A erhalten, wenn Sie es brauchen.

Ansonsten ist es nur ein einfaches UPDATE mit einem JOIN:

UPDATE B 
SET 
    StoreId = A.StoreID 
FROM 
    Table_B B 
INNER JOIN TABLE_A A ON A.UserId = B.UserId 

Sie können dies in einer Schleife setzen, die Chargen durchführt, wenn Sie benötigen, um auf die Größe des Updates zu reduzieren, so dass es doesn Überfluten Sie Ihr Transaktionslog nicht. Es gibt ein paar Möglichkeiten, dies zu tun. Ein Beispiel:

DECLARE 
    @batch_size INT = 10000, 
    @min_user_id INT = 1, 
    @max_user_id INT 

SELECT @max_user_id = MAX(UserId) FROM Table_A 

WHILE (@min_user_id <= @max_user_id) 
BEGIN 
    UPDATE B 
    SET 
     StoreId = A.StoreID 
    FROM 
     Table_B B 
    INNER JOIN TABLE_A A ON A.UserId = B.UserId 
    WHERE 
     B.UserId BETWEEN @min_user_id AND @min_user_id + @batch_size 

    SET @min_user_id = @min_user_id + @batch_size + 1 
END 
+1

Sehr gute Antwort – Lamak

+0

Ich wünschte, ich nur in gehen könnte und diese Spalte fallen, aber ich kam zu diesem Projekt viele Jahre, nachdem es erstellt wurde. Es würde einige Änderungen an der Front-End-Website sowie an unserem EDMX erfordern, um unnötige Spalten an dieser Stelle einzufügen und zu löschen. Große Antwort obwohl! Ich schätze die schnelle Antwort! – akaWizzmaster

0
select 1 
while (@@rowcount > 0) 
begin 
    UPDATE top(1000) B 
    SET b.StoreId = A.StoreID 
    FROM Table_B B 
    INNER JOIN TABLE_A A ON A.UserId = B.UserId 
    where b.StoreId <> A.StoreID 
     or b.StoreId is null 
end 
Verwandte Themen