2012-02-13 3 views
5

제가 일하고있는 회사는 트랜잭션으로 매 10 초마다 기록되는 거대한 로그/저널 테이블을 가지고 있습니다. 이 테이블에있는 많은 데이터를 복사하고 그 테이블에서 삭제하고 싶습니다. 이전 데이터의 약 75 %가 아카이브 테이블이나 기타 테이블에 저장 될 수 있기 때문입니다. 그러나이 작업을 잘못 수행하면 테이블이 잠길 수 있습니다. 그것은 재앙이 될 것입니다.거대한 생산 테이블에서 데이터 복사하기

이전 질문에서 한 남자가 이와 비슷한 것을 생각해 냈습니다.이 모든 것이 엉망이되지는 않을 것이라는 것을 알고 싶습니다. 놀럭은 나를 안전하게 지키기에 충분하고 모든 글은 잘 작동합니까? 그렇지 않다면 어떻게해야합니까?

set identity_insert newtable on 
DECLARE @StartID bigint, @LastID bigint, @EndID bigint 
select @StartID = max(id)+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 
+1

기존 레코드를 삭제하려는 계획을 제외하고 이것은 굉장합니다. 일종의 잠금없이 일을 처리하는 방법이 아닙니다. – JNK

+0

그래, 나는 조금 질문을 분명히했다. 그래서 일반적인 DB 작업의 방해가되지 않으면 서 오래된 레코드를 삭제하는 가장 좋은 방법은 무엇일까요? –

답변

3

목록을 생성 할 때 매우주의해야하지만, 일괄 삭제를 실행해야합니다.

INSERT의 경우 루프가 WHILE 일 필요는 없습니다. DELETE를 들어,하지만,이 같은 (조정 필요에 일괄 처리 크기)를 사용합니다 :

WHILE 1=1 
BEGIN 
    DELETE TOP (10000) o 
    FROM OldTable o 
    INNER JOIN NewTable N 
     ON o.id = n.id 
    IF @@ROWCOUNT < 10000 BREAK; 
END 

이 것만큼 삭제 기록이 있기 때문에 한 번에 DELETE 10K 기록합니다.

+0

나는 큰 테이블로 과거에 일괄 적으로 레코드를 보관 및 삭제하는 비슷한 작업을 해왔습니다. . 기본적으로 그것은 당신의 코드처럼 보였지만 while 루프 안에는 "begin tran"과 "commit tran"이 있습니다. 그런 다음 로그를 백업하고 자르고 자랐습니다. –

+0

그는 논쟁이 걱정된다면 테이블을 잠글 것이므로 트랜잭션을 수행하지 않을 것입니다. – JNK

+0

JNK에게 감사드립니다. 그렇다면 복사를 먼저하고 나서 삭제를 권장합니다. 내가 걱정할 필요가있는 다른 것? 미안하지만, 나는 단지 편집증에 빠졌어.하지만 그것이 효과가있는 것 같아. –

0

하나의 옵션은 시간 단위로 테이블을 분할하는 것입니다 (당신이 그 모든 삽입에 GETDATE() 디폴트 테이블의 DATETIME 열이 가정). 파티션이 있으면 현재 파티션에 영향을주지 않고 이전 파티션에서 유지 보수 (삭제, 복사 등)를 수행 할 수 있습니다.

+1

그는 선택할 수있는만큼 테이블을 잠그는 것에 관심이 있으며 파티션 구성표를 추가 할 것을 제안하고 있습니까? 나는 꽤 잠금을 일으킬 것이라고 확신한다. ... – JNK

+0

@JNK 네, 그렇지만 미래의 계획된 가동 중단 시간의 일부일 수 있습니다. –

관련 문제