Miałem ten sam problem, z wyjątkiem tego, że mam tabelę z 2 miliardami wierszy, więc plik dziennika rozrósłby się bez końca, gdybym to zrobił, nawet przy modelu odzyskiwania ustawionym na Logowanie zbiorcze:
insert into newtable select * from oldtable
Więc operuję na blokach danych. W ten sposób, jeśli transfer zostanie przerwany, po prostu go zrestartujesz. Ponadto nie potrzebujesz pliku dziennika tak dużego jak tabela. Wydaje się również, że masz mniej wejścia/wyjścia tempdb, nie wiesz dlaczego.
set identity_insert newtable on
DECLARE @StartID bigint, @LastID bigint, @EndID bigint
select @StartID = isNull(max(id),0) + 1
from newtable
select @LastID = max(ID)
from oldtable
while @StartID < @LastID
begin
set @EndID = @StartID + 1000000
insert into newtable (FIELDS,GO,HERE)
select FIELDS,GO,HERE from oldtable (NOLOCK)
where id BETWEEN @StartID AND @EndId
set @StartID = @EndID + 1
end
set identity_insert newtable off
go
Być może trzeba będzie zmienić sposób postępowania z identyfikatorami, działa to najlepiej, jeśli tabela jest pogrupowana według identyfikatorów.