Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Der schnellste Weg, um 120 Millionen Datensätze zu aktualisieren

Der einzige vernünftige Weg, eine Tabelle mit 120 Millionen Datensätzen zu aktualisieren, ist ein SELECT Anweisung, die eine Sekunde füllt Tisch. Dabei müssen Sie aufpassen. Anleitung unten.

Einfacher Fall

Für eine Tabelle ohne Clustered-Index während einer Zeit ohne gleichzeitige DML:

  • SELECT *, new_col = 1 INTO clone.BaseTable FROM dbo.BaseTable
  • Indizes, Constraints usw. für neue Tabelle neu erstellen
  • Altes und Neues wechseln mit ALTER SCHEMA ... TRANSFER.
  • alte Tabelle löschen

Wenn Sie kein Klonschema erstellen können, genügt ein anderer Tabellenname im selben Schema. Denken Sie daran, alle Ihre Beschränkungen und Auslöser (falls zutreffend) nach dem Wechsel umzubenennen.

Nicht einfacher Fall

Erstellen Sie zuerst Ihre BaseTable neu mit demselben Namen unter einem anderen Schema, zB clone.BaseTable . Die Verwendung eines separaten Schemas vereinfacht den späteren Umbenennungsprozess.

  • Den gruppierten Index einschließen , wenn anwendbar. Denken Sie daran, dass Primärschlüssel und Unique Constraints geclustert werden können, aber nicht unbedingt.
  • Identitätsspalten und berechnete Spalten einschließen , falls zutreffend.
  • Fügen Sie Ihre neue INT-Spalte hinzu , wo immer es hingehört.
  • Nicht einschließen eine der folgenden:
    • Auslöser
    • Fremdschlüsseleinschränkungen
    • Nicht-Cluster-Indizes/Primärschlüssel/eindeutige Beschränkungen
    • Check Constraints oder Default Constraints. Standardwerte machen keinen großen Unterschied, aber wir versuchen, die Dinge so gering wie möglich zu halten.

Testen Sie dann Ihre Einfügung mit 1000 Zeilen:

-- assuming an IDENTITY column in BaseTable
SET IDENTITY_INSERT clone.BaseTable ON
GO
INSERT clone.BaseTable WITH (TABLOCK) (Col1, Col2, Col3)
SELECT TOP 1000 Col1, Col2, Col3 = -1
FROM dbo.BaseTable
GO
SET IDENTITY_INSERT clone.BaseTable OFF

Untersuchen Sie die Ergebnisse. Wenn alles in Ordnung erscheint:

  • die Klontabelle abschneiden
  • Stellen Sie sicher, dass sich die Datenbank im massenprotokollierten oder einfachen Wiederherstellungsmodell befindet
  • Führen Sie die vollständige Einfügung durch.

Dies wird eine Weile dauern, aber nicht annähernd so lange wie ein Update. Überprüfen Sie nach Abschluss die Daten in der Klontabelle, um sicherzustellen, dass alles korrekt ist.

Erstellen Sie dann alle nicht geclusterten Primärschlüssel/eindeutigen Einschränkungen/Indizes und Fremdschlüsseleinschränkungen (in dieser Reihenfolge) neu. Standard neu erstellen und Einschränkungen überprüfen, falls zutreffend. Erstellen Sie alle Trigger neu. Erstellen Sie jeden Constraint, Index oder Trigger in einem separaten Batch neu. zB:

ALTER TABLE clone.BaseTable ADD CONSTRAINT UQ_BaseTable UNIQUE (Col2)
GO
-- next constraint/index/trigger definition here

Verschieben Sie abschließend dbo.BaseTable in ein Sicherungsschema und clone.BaseTable zum dbo-Schema (oder wo auch immer Ihre Tabelle leben soll).

-- -- perform first true-up operation here, if necessary
-- EXEC clone.BaseTable_TrueUp
-- GO
-- -- create a backup schema, if necessary
-- CREATE SCHEMA backup_20100914
-- GO
BEGIN TRY
  BEGIN TRANSACTION
  ALTER SCHEMA backup_20100914 TRANSFER dbo.BaseTable
  -- -- perform second true-up operation here, if necessary
  -- EXEC clone.BaseTable_TrueUp
  ALTER SCHEMA dbo TRANSFER clone.BaseTable
  COMMIT TRANSACTION
END TRY
BEGIN CATCH
  SELECT ERROR_MESSAGE() -- add more info here if necessary
  ROLLBACK TRANSACTION
END CATCH
GO

Wenn Sie Speicherplatz freigeben müssen, können Sie Ihre ursprüngliche Tabelle zu diesem Zeitpunkt löschen, obwohl es ratsam ist, sie noch eine Weile zu behalten.

Idealerweise ist dies natürlich offline Betrieb. Wenn Personen Daten ändern, während Sie diesen Vorgang ausführen, müssen Sie einen True-up-Vorgang mit dem Schemaschalter durchführen. Ich empfehle, einen Trigger auf dbo.BaseTable zu erstellen um alle DML in einer separaten Tabelle zu protokollieren. Aktivieren Sie diesen Trigger, bevor Sie mit dem Einfügen beginnen. Verwenden Sie dann in derselben Transaktion, in der Sie die Schemaübertragung durchführen, die Protokolltabelle, um ein True-up durchzuführen. Testen Sie dies zuerst an einer Teilmenge der Daten! Deltas sind leicht zu vermasseln.