Aktualizacja 700 milionów wierszy do tej samej wartości

12

Mam hurtownię danych (wyrocznię), w której muszę ustawić kolumnę na tę samą wartość dla wszystkich 700 milionów wierszy.

Nie mam dostępu administratora ani dostępu do administratora, więc należy to zrobić za pomocą podstawowego narzędzia SQL i nie tworzy się tabeli tymczasowej.

Dalsze komplikowanie spraw polega na tym, że jeśli spróbuję wykonać prostą aktualizację, gdzie 1 = 1, zabraknie miejsca na ponawianie.

Sposób, w jaki mam teraz działający, jest taki:

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

ale wiem, że to prawdopodobnie naiwne i musi istnieć szybsze i bardziej eleganckie rozwiązanie.

słuchałem
źródło
Czy tabela jest podzielona na partycje?
Jack mówi, że spróbuj topanswers.xyz
Nie wierzę w to. Istnieje kilka indeksów, ale żaden z nich nie dotyczy kolumny, którą aktualizuję.
obejrzał

Odpowiedzi:

4

Jeśli masz miejsce, możesz CTAS przy użyciu minimalnego cofania / ponawiania . Jeśli masz jakieś indeksy, robienie tego w jakikolwiek inny sposób będzie bardzo wolne i generuje logowanie jak szalone.

W przypadku, gdy masz pojedynczy IOT bez dodatkowych indeksów lub pojedynczy klaster tabeli, możesz przejść przez aktualizację klucza podstawowego / klastra w porcjach bez konieczności ponownego skanowania całej tabeli w celu znalezienia pól, które nie zostały jeszcze zaktualizowane.

--edytować

Nie jestem w stanie utworzyć tabeli pomocniczej ... Istnieje kilka indeksów, ale żaden z nich nie dotyczy kolumny, którą aktualizuję.

Następnie sugeruję podzielenie tabeli na części w celu przetworzenia przy użyciu czegoś, na którym indeksujesz (nawet jeśli jest to pojedyncza kolumna, możesz podzielić ją na zakresy wartości). To spowoduje wykonanie FTS raz zamiast jednego dla każdego fragmentu, jak w twoim kod. Będziesz musiał żyć z okropną ilością przeróbek i wyczyścisz również swoje miejsce cofania (więc nie będzie później retrospekcji)

--edit2

jeśli możesz dodać / zmienić nazwę / upuścić kolumny, możesz to zrobić bardzo skutecznie , ale tylko na 11g

Jack mówi, że spróbuj topanswers.xyz
źródło
1
Jeśli Twój DBA pozwala, to NOLOGGINGspowoduje unieważnienie hotstandbys.
Gajusz
Rzeczywiście, późniejsza kopia zapasowa byłaby również dobrym pomysłem - ale to jest magazyn i nologgingnarzędzie do magazynów
Jack mówi, spróbuj wypróbować topanswers.xyz
Nie jestem w stanie stworzyć drugiego stołu, z pewnością nie tak dużego jak pierwszy, nawet jeśli tylko tymczasowy.
obejrzał
Twój link 11g wyglądał obiecująco, ale widzę tam komentarze, że dla 60-metrowego stołu wciąż było strasznie powolne z powodu konieczności ustawiania wartości dla każdego wiersza. Ponieważ mój stół jest 10 razy większy, ta metoda może nie być ulepszeniem.
obejrzał
@ słuchaj nie, na 11g ta operacja jest szybka i nie ustawia wartości dla każdego wiersza „dla niektórych typów tabel (na przykład tabel bez kolumn LOB)” . Wypróbuj na podzbiorze swojej tabeli ( create table foo as select * from bar where rownum<100000)
Jack mówi, spróbuj wypróbować topanswers.xyz
1

Jeśli używasz 11 g, upuść kolumnę i dodaj ją z powrotem jako kolumnę NOT NULL z wartością domyślną. Jest to sprzeczne z intuicją, ale Oracle zapisze domyślną wartość w definicji tabeli, zastępując ją w czasie wykonywania.

Adam Musch
źródło