2012-03-23 2 views
1

디스크 공간이 부족하여 약 600 만 행의 테이블에서 약 500 만 행을 삭제해야합니다. 그들을 삭제하는 빠른 방법 있는가? 일괄 처리에서 delete를 호출하려고 시도했지만 실행하는 데 오랜 시간이 걸리고 때로는 잠금 때문에 오류가 발생하고 아무 것도하지 않습니다.디스크 공간이 부족할 때 테이블에서 여러 행 삭제

편집 :

내가

delete from <table> where updated_timestamp < '2012-02-20' 

같은 작은 배치를 얻기 위해, 이제 쿼리를하고 있었는데, 쿼리 내가 점점 않은 다음

delete from <table> where id < [100000 row increments] 

오류는 있었다 테이블에 자물쇠를 채우지 못했습니다. 나는 순간에 정확한 텍스트를 가지고 있지 않지만, 내가 다시 그것으로 실행하는 경우, 여기

답변

2

행을 삭제하는 유일한 방법을 붙여 넣을 수 있습니다 것은에 하나 DELETE FROM <table> WHERE <some condition>, 또는 TRUNCATE TABLE <table> 또는 DROP TABLE <table> 중 모든 행을 삭제 (그런 다음 다시 작성하십시오).

더 구체적인 답변을 드릴 수있는 정보를 제공하지 못했습니다. 두려워합니다. WHERE 절의 조건을 사용하여 작은 행 집합 (일괄 처리)에서이 작업을 수행 할 수 있습니다. (때로는 "오류를 throw합니다"는 "오류가 발생했습니다"에 대한 정보가 없으면 "오류가 발생했습니다"는 의미가 없으므로이를 해결하는 데 도움이되지 않습니다.)

+0

불투명 한 점에 대해 나는 위의 질문을 편집했습니다. – Carlos

1

내 상황에 대한 제안 사항은 다음과 같습니다. 레코드를 삭제할 때 로그에 삭제하는 모든 레코드를 기록하기 때문에 추가 디스크 공간이 필요하기 때문에 단단한 "temp"테이블로 유지하려는 백만 레코드를 선택한 다음 테이블을 자릅니다. 테이블을 자른 후 솔리드 "temp"테이블의 레코드를 원래 테이블에 다시 추가하고 솔리드 "temp"테이블을 삭제합니다.

다른 작업은 데이터베이스에서 CHECKPOINT을 실행 한 다음 축소하는 것입니다. 디스크의 여유 공간을 확보해야합니다.

0

이전 두 답변은 절대적으로 정확합니다.

은 무엇 당신이 찾고있는 것은 당신이 (가) 테이블을 참조하는 외래 키를 가지고, 또는 (b) ID 열이있는 경우이 조금 더 복잡하게 다음

SELECT * INTO into #temp FROM <table> WHERE updated_timestamp >= '2012-02-20' 
TRUNCATE TABLE <table> 
INSERT INTO <table> SELECT * FROM #temp 

입니다. 전자의 경우 외래 키 제약 조건을 통해 테이블의 레코드를 참조하는 모든 레코드를 삭제하고 제약 조건을 삭제 한 다음 외래 키를 자르고 다시 작성해야합니다. 후자의 경우 삽입 문에 대해 다음을 사용할 수 있습니다.

SET IDENTITY INSERT <table> ON 
INSERT INTO <table> (<field_list>) 
SELECT <field_list>) FROM #temp 
SET IDENTITY INSERT <table> ON 
0

로그가 1 년 이상 지난 로그 테이블을 삭제하는 코드입니다. 배치 루프.

declare @batch int 
declare @i int 
declare @j int 
set @batch = 1000 
set @j = (select (COUNT(*)/@batch) + 1 from LOG_TABLE 
       where ACCESS_DATE < dateadd(year,-1,getdate())) 
set @i = 0 
print @j 

while (@i < @j) 
BEGIN 



delete top (@batch) 
from LOG_TABLE 
where ACCESS_DATE < dateadd(year,-1,getdate()) 
SET @i = @i + 1 
END 
관련 문제