2010-06-21 4 views
0

다음 릴리스의 일부로 수백만 행을 업데이트해야하지만 그렇게하면 트랜잭션 로그가 채워지고 실패합니다. 몇 가지 아이디어가 있지만 저는 SQL 전문가가 아니므로 잘 모르는 문제가있을 것이라고 확신합니다.수백만 행의 업데이트 쿼리가 트랜잭션 로그를 채움

타당한 점 :

  1. 나는 그래서 아무 수동 개입과 ​​T-SQL 방법을 필요로하는 운영 팀에 스크립트를 넘겨해야합니다.
  2. 분명히 트랜잭션 로그는 15 분마다 재활용됩니다. (나는 아래처럼 catch 블록에 WAITFOR DELAY '00:15:00'으로 try-catch를 사용하여 루프를 작성하는 것에 대해 생각해 보았습니다)
  3. (EDIT) 데이터 이외에는 수정할 수 없습니다.
  4. (EDIT) 외래 키 열을 다른 기존 키로 변경하는 간단한 업데이트입니다.

감사합니다,

DECLARE 
    @AffectedRows int 

SET @AffectedRows = 0 

WHILE @AffectedRows < @RowsToUpdate 
BEGIN 
    BEGIN TRY 
     BEGIN TRAN 
     -- Do some updates 
     SET @AffectedRows = @AffectedRows + @@RowCount 
     COMMIT TRAN 
    END TRY 
    BEGIN CATCH 
     PRINT ERROR_MESSAGE() 
     WAITFOR DELAY '00:15:00' 
    END CATCH 
END 

PRINT @AffectedRows 
+0

트랜잭션을 사용하지 않습니까? –

답변

2

결국 필자가 이미 작성한 예제가 가장 효과적이었습니다. 트랜잭션 로그 가득 참 오류가 catch에 잡히고 15 분이 지나면 로그를 재활용 할 수 있습니다.

DECLARE 
    @AffectedRows int 

SET @AffectedRows = 0 

WHILE @AffectedRows < @RowsToUpdate 
BEGIN 
    BEGIN TRY 
     BEGIN TRAN 
     -- Do some updates 
     SET @AffectedRows = @AffectedRows + @@RowCount 
     COMMIT TRAN 
    END TRY 
    BEGIN CATCH 
     PRINT ERROR_MESSAGE() 
     WAITFOR DELAY '00:15:00' 
    END CATCH 
END 

PRINT @AffectedRows 
1

몇 점/아이디어 :

  1. 당신은 당신이 그렇게 그것을 기입하지 않습니다 원하는 크기로 트랜잭션 로그를 확장 할 수 있습니다.
  2. 트랜잭션 로그가 너무 커지면 항상 DB를 백업하고 로그를자를 수 있습니다.
  3. 데이터를 일괄 적으로 처리 할 수 ​​있습니다 (한 번에 백만 개씩 수행)
  4. 데이터를 작업 테이블에 복사 한 다음 처리가 완료되면 sp_rename 할 수 있습니다. 당신은 니블 링을 개혁하고
+0

어떤 종류의 스키마 나 관리자 유형을 변경할 수 없다는 점을 잊어 버렸습니다. 이를 반영하기 위해 질문을 업데이트했습니다. 일괄 적으로 업데이트를 수행하는 예가 있습니까? –

+0

@Phil 그것은 테이블의 스키마에 따라 다르며, 업데이트가 발생했거나 테이블을 분할하는 자연스러운 방법이 있다면 스키마와 업데이트 문을 포함하도록 질문을 편집하십시오. –

+0

ID를 업데이트하고 있습니다. 다른 ID이므로'where ID = @ OldID'를 사용하고 있습니다. –