Eu tive o mesmo problema, exceto que eu tenho uma tabela com 2 bilhões de linhas, então o arquivo de log cresceria muito se eu fizesse isso, mesmo com o modelo de recuperação definido como Bulk-Logging:
insert into newtable select * from oldtable
Então eu opero em blocos de dados. Dessa forma, se a transferência for interrompida, basta reiniciá-la. Além disso, você não precisa de um arquivo de log tão grande quanto a tabela. Você também parece ter menos E/S tempdb, não sei por que.
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
Pode ser necessário alterar a forma como lida com IDs, isso funciona melhor se sua tabela estiver agrupada por ID.