Hinzufügen von Spalten zu Produktionstabellen

28

Was ist die beste Möglichkeit, um Spalten zu großen Produktionstabellen in SQL Server 2008 R2 hinzuzufügen? Laut Online-Büchern von Microsoft:

Die in ALTER TABLE angegebenen Änderungen werden sofort implementiert. Wenn die Änderungen Änderungen an den Zeilen in der Tabelle erfordern, aktualisiert ALTER TABLE die Zeilen. ALTER TABLE erwirbt eine Schemaänderungssperre für die Tabelle, um sicherzustellen, dass während der Änderung keine anderen Verbindungen auf die Metadaten der Tabelle verweisen, mit Ausnahme von Online-Indexoperationen, für die am Ende eine sehr kurze SCH-M-Sperre erforderlich ist.

(http://msdn.microsoft.com/en-us/library/ms190273.aspx)

Bei einer großen Tabelle mit Millionen von Zeilen kann dies eine Weile dauern. Ist ein Ausfall die einzige Option? Was ist der beste Weg, um mit dieser Situation umzugehen?

sh-beta
quelle
1
Neuester Artikel zu diesem Problem: sqlservercentral.com/articles/Change+Tracking/74397
8kb

Antworten:

27

"Es hängt davon ab, ob"

Wenn Sie eine Spalte hinzufügen, für die keine Daten zu den Zeilen hinzugefügt werden müssen, kann dies recht schnell gehen.

Das Hinzufügen eines Int oder Char erfordert beispielsweise physische Zeilenbewegungen. Das Hinzufügen eines nullfähigen Varchars ohne Standard sollte nicht erfolgen (es sei denn, die NULL-Bitmap muss erweitert werden).

Sie müssen es mit einer wiederhergestellten Kopie der Produktion versuchen, um einen Kostenvoranschlag zu erhalten

Das Erstellen, Kopieren und Umbenennen einer neuen Tabelle kann länger dauern, wenn Sie Indizes und Schlüssel für eine Milliardenzeilentabelle erneut hinzufügen müssen.

Ich habe Milliarden Zeilentabellen geändert, die einige Sekunden brauchten, um eine nullfähige Spalte hinzuzufügen.

Habe ich gesagt, zuerst ein Backup zu machen?

gbn
quelle
2
+1 auf dem Backup. und stellen Sie sicher, dass Sie auch über genügend Protokollspeicher verfügen.
SqlACID
Können Sie erklären, warum das Hinzufügen eines Int oder Char physische Zeilenbewegungen erfordert?
sh-beta
5
Meinten Sie "erfordert nicht" das Hinzufügen von Daten zu den Zeilen in Ihrer zweiten Zeile?
Ben Brocka
21

Wenn die Spalte NULL-fähig ist, sollte die Auswirkung vernachlässigbar sein. Wenn die Spalte nicht NULL sein kann und der Wert festgelegt werden muss, kann dies ganz anders sein. Was ich in diesem Fall tun würde, ist, anstatt eine Nicht-Null- und eine Standardbedingung in einer Aufnahme hinzuzufügen, effektiv Daten zu jeder Zeile hinzuzufügen:

  • Füge die Spalte als NULLable hinzu - sollte in den meisten Fällen schnell gehen
  • Aktualisieren Sie die Werte auf den Standardwert
    • Sie können dies bei Bedarf in Chargen tun
    • Sie können dies auch verwenden, um bedingte Logik anzuwenden, bei der einige Zeilen möglicherweise nicht den Standard erhalten
  • Fügen Sie die Nicht-Null- / Standardeinschränkungen hinzu
    • Dies ist schneller, wenn keine der Daten NULL ist, aber dennoch messbar sein sollte

Stimmen Sie mit @gbn überein, dass Sie dies testen können, indem Sie eine Kopie der Produktion wiederherstellen und dort testen ... Sie erhalten eine gute Vorstellung vom Timing (vorausgesetzt, die Hardware ist etwas ähnlich) und Sie können auch die Auswirkungen auf das Transaktionsprotokoll sehen.

Aaron Bertrand
quelle
Was das letzte angeht: •add the not null/default constraintsIch bin mir nicht sicher, ob es damit kein potenzielles Problem gibt ... Wenn MSSQL (sogar 2008R2) eine Spalte, die nicht null ist, in null ändert, können Sie sie, wenn Sie eine Ablaufverfolgung aktivieren, tatsächlich unter der Decke sehen Führen Sie eine vollständige Aktualisierung jeder Zeile der Tabelle durch, dh update table1 set column1 = column1ich gehe davon aus, dass die Nicht-Null-Überprüfung auf völlig idiotische Weise erfolgt. Diese Transaktion ist doppelt so groß wie die Tabelle (vor und nach den Seiten), sodass eine DW-Tabelle sehr umfangreich sein kann. Bisher mussten wir Daten ausbCPen, abschneiden, null auf nicht null ändern und dann bCPen.
Wenn jemand einen Weg kennt, weiß ich es gerne ... Im Gegensatz dazu bewirkt das Ändern von Null in Nicht-Null in Oracle eine Sperre, dann ein Auswählen, um zu überprüfen, ob keine Nicht-Nullen vorliegen, und dann eine sofortige Aktualisierung der reinen Metadaten.
Hey @Mike, das klingt nach einer guten Frage.
Derek Downey
4

Haben Sie überlegt:

  1. Erstellen einer neuen Tabelle, die die Änderungen an der Tabellendefinition enthält.
  2. Einfügen in die neue Tabellendefinition Auswahl aus der Originaltabelle.
  3. Die ursprüngliche Tabelle in _orig umbenennen und dann die neue Tabelle in den ursprünglichen Tabellennamen umbenennen.

Der Nachteil hierbei ist, dass Sie über ausreichend Speicherplatz in der Datenbank verfügen müssen, um diese Änderung vorzunehmen. Möglicherweise benötigen Sie weiterhin eine Lesesperre für die Tabelle, um schmutzige Lesevorgänge zu verhindern.

Sie minimieren jedoch die Auswirkungen auf die Endbenutzer, wenn die Chance besteht oder ein gleichzeitiger Zugriff auf die Originaltabelle erforderlich ist. Es sollte auch die Sperrdauer minimieren.

RobPaller
quelle
Würden Sie keine Schreibsperre benötigen , anstatt zu lesen? Es ist in Ordnung, wenn Benutzer Daten in der alten Tabelle sehen. Sie möchten lediglich nicht, dass sie Änderungen festschreiben, die nach Abschluss des Puffertauschs überschrieben werden.
Jon of All Trades
Das habe ich mir mit meinem Data Warehouse überlegt, wo sich Änderungen etwas einfacher steuern lassen. In einer OLTP-Situation, in der Sie Recht haben, ist eine Schreibsperre erforderlich, um zu verhindern, dass Änderungen an der Tabelle vorgenommen werden.
RobPaller