2013-05-22 4 views
0

13 개월이 넘은 데이터의 경우 데이터베이스에서 많은 양의 기록 데이터를 제거하려고합니다.SQL Server 데이터베이스에서 많은 양의 데이터 삭제

잘라 내기 저장 프로 시저를 작성했지만 실행하려고 할 때 두 가지 문제가 있습니다.

문제 1 - 삭제는 데이터베이스 트랜잭션 로그를 가득 채우고 디스크 드라이브의 공간이 부족할 때 데이터베이스를 손상시킵니다.

문제 2 - 스크립트 자체를 실행하는 데 시간이 오래 걸립니다.

아래는 SP의 문은 다음과 같습니다

DELETE FROM Header_Table WHERE Date_DT < @date 

Header_Table 표는 10 개 다른 테이블과 ON DELETE CASCADE 관계를 가지고있다. 내가 Header_Table

  1. 하여 10 표 참조에서뿐만 아니라 그것이 Header_Table 테이블에서 데이터를 삭제 위의 쿼리를 발생 그리고 두 번째 문에, 내가 임시로 Information_Table 테이블에서 데이터를 삽입하고 그 때 의미 표. 아래의 문장에서

    INSERT INTO Temp_Table (Key, AccNum, Exp, Name_VC) 
        SELECT 
         in.Key AS CRD_NFO_CIK, 
         in.Acct_Num AS CRD_NFO_ACC, 
         in.Exp AS CRD_NFO_EXP, 
         in.Name_on_Card_VC AS CRD_NFO_NAME  
        FROM 
         Information_Table in 
        LEFT OUTER JOIN 
         Card_T crd ON in.Key = crd.Card_Info_Key 
        LEFT OUTER JOIN 
         Business_T business ON in.Key = business.CC_Info_Key 
        LEFT OUTER JOIN 
         Con_T contr ON in.Key = contr.Card_Info_Key 
        LEFT OUTER JOIN 
         Customer_Payment_T customer ON in.Key = customer.Card_Info_Key 
        LEFT OUTER JOIN 
         Temp_Table Temp ON in.Key = Temp.Key 
        WHERE 
         Temp.Key IS NULL AND 
         crd.Card_Info_Key IS NULL AND 
         business.CC_Info_Key IS NULL AND 
         contr.Card_Info_Key IS NULL AND 
         customer.Card_Info_Key IS NULL 
    
  2. , 사실 당신은 항상 내가 데이터를 삭제한다 제안 chunks.What에서 데이터를 삭제해야 Information_Table에서 이러한 경우

    DELETE info 
    FROM Information_Table in  
    LEFT OUTER JOIN Card_T crd ON in.Key = crd.Card_Info_Key  
    LEFT OUTER JOIN Business_T business ON in.Key = business.CC_Info_Key  
    LEFT OUTER JOIN Con_T contr ON in.Key = contr.Card_Info_Key  
    LEFT OUTER JOIN Customer_Payment_T customer ON in.Key = customer.Card_Info_Key 
    WHERE 
        crd.Card_Info_Key IS NULL AND 
        business.CC_Info_Key IS NULL AND 
        contr.Card_Info_Key IS NULL AND 
        customer.Card_Info_Key IS NULL 
    
+1

"Header_Table 테이블에는 10 개의 다른 테이블과 ON DELETE CASCADE 관계가 있습니다." - 이것은 분명히 그 테이블에 대한 삭제 작업에 많은 시간을 할애 할 것입니다. 각 테이블에서 레코드를 차례대로 "수동으로"삭제하면 더 많은 성능을 얻을 수 있습니다. – JimmyB

+0

@HannoBinder 우리는 10 개의 테이블에 대한 CASCADE의 관계를 더 이상 알지 못합니다. 이것은 클라이언트 프로덕션 데이터베이스이므로 테이블 레코드를 수동으로 삭제하는 데 많은 위험을 감수 할 수 없습니다. –

+0

흠, 너무 나쁨. 트랜잭션 로그 [this] (http://databases.about.com/od/sqlserver/a/truncate_shrink.htm)가 도움이 될 수 있습니다. - * 배치로 레코드를 삭제하면 어쨌든 갈 수 있으며, 중단없이 작업이 실행되는 기간을 제어 할 수 있습니다. 예를 들어 4 주분의 데이터를 일괄 처리하고 테이블의 성장을 따라 잡을 때까지이 배치 중 하나를 매일 삭제할 수 있습니다. 각 배치 후에 잠금을 해제하고 트랜잭션 로그를 축소 할 수 있도록 (적어도) "완결"하는 것을 잊지 마십시오. – JimmyB

답변

2

의 데이터를 삭제하고 배치로.

+0

이것은 트랜잭션 로그 파일을 늘리지 않는 것이 좋지만 이전과 같이이 sql을 실행하는 데 동일한 시간이 걸립니다. –

+0

그래도 이것을 달성하기위한 가장 안전하고 안전한 방법입니다. – AnandPhadke

+0

동의합니다. 이 작업을 수행해야 할 때마다 한 번에 청크를 삭제합니다. 상위 항목 삭제 # 사용 ... 트랜잭션 로그가 채워지는대로 복구 모델을 전체에서 간단하게 변경하는 것 외에는 알 수없는 방법은 없습니다. 트랜스 로그가 있으므로 변경 사항을 되돌릴 수 있습니다. 근본적으로 그 일을하는 당신. 시스템이 조용한 상태에서 단순 모드로 변경되면 삭제 한 다음 다시 전체로 변경할 수 있습니까? –

0

얼마나 자주 트랜잭션 로그를 백업합니까? 자체 배치에서 각 배치가있는 배치를 삭제하면 시스템이 해당 시스템을 백업하도록 설정되지 않은 경우 (또는 부적절한 긴 스케줄에서만) 트랜잭션 로그가 가득 채지 않도록 트랜잭션 로그 백업을 자주 수행해야합니다. 참고 트랜잭션 로그 백업은 데이터베이스 백업과 완전히 다르며 트랜잭션 시스템에서 자주 발생합니다. 우리는 15 분마다 백업됩니다. 또한 (개인적으로 허용하지 않은) 계단식 계좌가 있기 때문에, 아마도 작은 배치가 필요할 것입니다.

관련 문제