2011-05-08 1 views
7

거대한 테이블 (30 억 개의 행)이 있는데, 불행히도 대부분 만료 된 데이터가 포함되어 있습니다. 만료 된 행을 모두 삭제하고 나머지는 보관하고 싶습니다.로그 파일이 제어 불능 상태가되지 않으면 서 거대한 테이블에서 만료 된 데이터를 삭제하려면 어떻게해야합니까?

나는이 같은 문을 실행할 수 있습니다

delete from giganticTable where exp_date < getDate() 

실행 계획은 어떻게 든 약 400 만 행이 삭제됩니다 것으로 추정하고있다.

실행하면 1 시간 후에 완료되지 않을뿐만 아니라 데이터베이스 트랜잭션 로그 파일도 6GB에서 90GB로 증가합니다. 이 상황이 발생하는 동안 데이터베이스는 대량 로그 복구 모델에 있음을 유의하십시오. 결국이 쿼리를 취소했습니다.이 작업을 수행하는 더 좋은 방법이 있어야합니다.

비슷한 작업을 수행하는 데 필요한 여러 테이블이 있습니다. 그 행들을 절대 복구 할 의사가 전혀 없다면이 행을 삭제하는 가장 빠르고 공간 효율적인 방법은 무엇일까요? 나는 마이크로 소프트 SQL 서버를 사용하고

주 2005

당신이 어떤 문제 때문에 테이블에 많은 작업을 수행 할 때 당신은 정말 로깅을 해제 바보 같은 것을 시도 엉망 싶지 않아

답변

3

긴 작업 동안 쉽게 데이터베이스 손상 및 기타 문제가 발생할 수 있습니다. 그러나 문제를 해결할 방법이 있습니다.

실제 테이블의 스키마와 일치하는 임시 테이블을 만듭니다. KEEP에 저장하려는 데이터로 채 웁니다. 그런 다음 원래 테이블을 자릅니다 (로그 파일에서 매우 빠르고 쉽습니다). 마지막으로 임시 테이블에서 원래의 (이제 비어있는) 테이블로 데이터를 이동하십시오.

자동 증가 기본 키를 사용하는 경우 필드에 원래의 키를 가져 가야합니다 (나중에 문제가 발생하지 않음).

+0

복구 모델 만 변경하면 데이터베이스가 손상되는 사례가 있습니까? – rsbarro

+0

@rsbarro - 복구 모드를 변경하는 것 뿐만이 아니라, 복구 모드가 부적절하게 설정되어있는 경우 큰 프로세스 동안 데이터베이스가 손상되는 것을 보았습니다. 이로 인해 데이터베이스가 유실됩니다. – IAmTimCorey

+0

나는 당신이 무엇을 얻고 있는지 알지만 간단하게 복구 모드를 설정한다고해서 당신이 데이터베이스를 잃어 버리는 것은 아닙니다. 단지 마지막 전체 백업으로 복원 할 수 있음을 의미합니다. 나는 당신의 대답이 복구 모드를 전환하는 것처럼 보일 뿐이므로 개인적으로 발생하지 않는 부패를 야기하기 때문에 묻고있었습니다. – rsbarro

9

많은 수의 행이있는 테이블에서 삭제를 수행하여 5000 개 정도의 행을 삭제할 때 유용하다는 것을 알았습니다 (보통 어떤 값이 가장 빠른지, 가끔은 5000 행인지, 가끔은 10,000인지 테스트합니다). , 등). 이렇게하면 하나의 명령문이 4 억 개의 레코드를 삭제할 때까지 오랜 시간 기다리지 않고 각 삭제 작업을 신속하게 완료 할 수 있습니다. SQL Server 2005에서

,이 같은 일이 (물론, 첫 번째 테스트하시기 바랍니다) 작동합니다 :

WHILE EXISTS (SELECT * FROM giganticTable WHERE exp_date < getDate()) 
BEGIN 
    DELETE TOP(5000) FROM giganticTable WHERE exp_date < getDate() 
END 

내가 로그 파일 크기를 수행 일괄 무엇을 삭제 볼 것입니다. 여전히 로그를 날려 버리는 경우 복구 모델을 Simple으로 변경하고 레코드를 삭제 한 다음 대량 로그로 다시 전환 할 수 있습니다. 단, 시스템에서 최근 데이터 손실을 허용 할 수있는 경우에만 가능합니다. 난 그 절차를 시도하기 전에 전체 백업을 확실히 만들 것입니다. 이 thread은 truncate 만 지정하여 로그를 백업하도록 작업을 설정할 수 있으므로 다른 옵션이 될 수도 있습니다. 다행스럽게도 테스트 할 수있는 인스턴스가 있지만 일괄 처리 된 삭제로 시작하여 성능 및 로그 파일 크기에 어떤 영향을 주는지 확인할 수 있습니다.

1

일일이 그렇게 했어야했기 때문에 한 번에 그렇게 큰 일을하지 못했습니다. 당신이 상황에 있기 때문에
, 여기 내 제안은 다음과 같습니다

  1. 분할 rsbarro 같은 작업을 말한다. while 문은 필요하지 않을 것입니다. 며칠 안에 처리 할 수 ​​있습니다.,

    delete from giganticTable where exp_date < '2013-08-07' 
    
  2. 내가 거대한 로그에 대한 좋은 생각이 없어 할 수있는 정말 좋은 방법이없는 것 같다 :
  3. 날짜를 기입 명시 적으로 좋아한다.

관련 문제