Historia pytania:
Masowa aktualizacja danych jest potrzebna podczas przenoszenia, migracji, naprawy logiki biznesowej. Typowy przykład: musisz zmienić status dziesiątek milionów wierszy w tabeli roboczej, nie zatrzymując usługi, zachowując dostępność i wydajność.
Problem:
Zwykły UPDATE bez ograniczeń działa wolno, może prowadzić do eskalacji blokad, blokuje tabelę i prowadzi do zbiorczego wycofania w przypadku błędu. Potrzebne jest podejście, które minimalizuje wpływ na użytkowników i zapewnia transakcyjność.
Rozwiązanie:
Przykład kodu:
-- Przykład aktualizacji paczki po 10 000 wierszy WHILE 1 = 1 BEGIN UPDATE TOP (10000) mytable SET status = 'archived', updated = GETDATE() WHERE status = 'active'; IF @@ROWCOUNT = 0 BREAK; END
Kluczowe cechy:
Czy można zrobić masowy UPDATE w jednej transakcji i nie zablokować tabeli?
Zazwyczaj nie. Duża transakcja blokuje tabelę/strony i zwiększa ryzyko blokad i timeoutów. Lepiej pracować w paczkach.
Czy obecność indeksów wpływa na prędkość masowej aktualizacji?
Tak. Każda aktualizacja pól indeksowanych wymaga przebudowy indeksu dla każdego wiersza. Czasami opłaca się tymczasowo usunąć indeksy, ale wymaga to głębokiej analizy.
Czy wszystkie wiersze są aktualizowane atomowo przy aktualizacjach paczkowych?
Nie, atomowość jest gwarantowana tylko w obrębie jednej paczki (limit wierszy/transakcji). Jeśli paczka zostanie przerwana, część wierszy będzie zaktualizowana, a część — nie. Dla prawdziwej atomowości — tylko pełny UPDATE w jednej transakcji, co jest niebezpieczne przy dużych objętościach.
Inżynier techniczny postanowił zaktualizować 10 mln wierszy jednym zapytaniem w produkcyjnej bazie danych: UPDATE mytable SET status = 'archived'. Strona "zamroziła się", wycofanie zajęło dziesiątki minut, wydajność ucierpiała.
Zalety:
Zapytanie podzielone na paczki po 10 000 wierszy z krótkimi transakcjami, aktualizacja odbywa się w godzinach roboczych bez przestojów.
Zalety: