Aktualisieren von 700 Millionen Zeilen auf denselben Wert

12

Ich habe ein Data Warehouse (Oracle), in dem ich eine Spalte für alle 700 Millionen Zeilen auf den gleichen Wert setzen muss.

Ich habe keinen Administratorzugriff oder Zugriff auf einen Administrator, daher muss dies mit einfachem SQL durchgeführt werden und es wird keine temporäre Tabelle erstellt.

Eine weitere Komplikation ist, wenn ich versuche, nur ein einfaches Update mit 1 = 1 durchzuführen, ist der Redo-Platz knapp.

Die Art, wie ich es jetzt laufen habe, ist eine Schleife wie diese:

loop
  update mytable set mycolumn = '1' where mycolumn is null and rownum < 50000;
  commit;
end loop

aber ich weiß, das ist wahrscheinlich naiv und es muss eine schnellere und elegantere Lösung geben.

Ich habe es geschafft
quelle
Ist die Tabelle partitioniert?
Jack sagt, versuchen Sie topanswers.xyz
Das glaube ich nicht. Es gibt einige Indizes, von denen jedoch keiner die Spalte betrifft, die ich aktualisiere.
30.

Antworten:

4

Wenn Sie über ausreichend Platz verfügen, können Sie CTAS mit minimalem Rückgängigmachen / Wiederherstellen ausführen . Wenn Sie überhaupt Indizes haben, ist eine andere Vorgehensweise sehr langsam und führt zu einer verrückten Protokollierung.

Wenn Sie eine einzelne IOT ohne Sekundärindizes oder einen einzelnen Tabellencluster haben, können Sie die Aktualisierung des Primär- / Clusterschlüssels in Blöcken schrittweise durchführen, ohne die gesamte Tabelle erneut durchsuchen zu müssen, um die noch nicht aktualisierten Felder zu finden.

--bearbeiten

Ich kann keine sekundäre Tabelle erstellen ... Es gibt einige Indizes, von denen jedoch keiner die Spalte betrifft, die ich aktualisiere.

Dann schlage ich vor, die Tabelle in Abschnitte zu unterteilen, um sie mit etwas zu verarbeiten, für das Sie eine Indizierung durchführen (auch wenn es sich um eine einzelne Spalte handelt, können Sie sie in Wertebereiche aufteilen). Auf diese Weise wird für jeden Abschnitt ein FTS einmal ausgeführt, anstatt einmal wie in Ihrem Code. Du wirst mit einer Menge Redo leben müssen und auch deinen Undo-Space löschen müssen (also keine Rückblende danach)

--edit2

Wenn Sie Spalten hinzufügen / umbenennen / löschen können, können Sie dies sehr effizient tun , jedoch nur mit 11 g

Jack sagt, versuchen Sie es mit topanswers.xyz
quelle
1
Wenn Ihr DBA dies NOLOGGINGzulässt, werden die Hotstandbys ungültig.
Gaius
In der Tat, und ein Backup danach wäre auch eine gute Idee - aber dies ist ein Lagerhaus und nologgingein Werkzeug für Lagerhäuser
sagt Jack, versuchen Sie topanswers.xyz
Ich bin nicht in der Lage, eine sekundäre Tabelle zu erstellen, sicherlich keine, die so groß ist wie die erste, auch wenn sie nur vorübergehend ist.
30.08.11
Ihr 11g-Link sah vielversprechend aus, aber ich sehe Kommentare darin, dass es für einen 60m-Tisch immer noch schrecklich langsam war, weil der Wert für jede Zeile festgelegt werden musste. Da mein Tisch 10x so groß ist, ist diese Methode möglicherweise keine Verbesserung.
31.08.11
@owook nein, bei 11g ist dieser Vorgang schnell und legt nicht für jede Zeile den Wert "für einige Tabellentypen (z. B. Tabellen ohne LOB-Spalten)" fest . Versuchen Sie es auf einer Teilmenge Ihrer Tabelle ( create table foo as select * from bar where rownum<100000)
Jack sagt, versuchen Sie topanswers.xyz
1

Wenn Sie mit 11g arbeiten, löschen Sie die Spalte und fügen Sie sie als NOT NULL-Spalte mit einem Standardwert hinzu. Dies ist nicht intuitiv, aber Oracle speichert den Standardwert in der Tabellendefinition und ersetzt ihn zur Laufzeit.

Adam Musch
quelle