모든 (1 천 2 백만) 레코드를 삭제 한 후 SQL Server “빈 테이블”이 느려 집니까? 세트를 준비하기 위해 테이블을 지 웠습니다. 그러나

약 150 개의 열이있는 SQL Server 2008 인스턴스가 있습니다. 이전에 약 1,200 만 개의 항목으로이 테이블을 채웠지만 이후 새 데이터 세트를 준비하기 위해 테이블을 지 웠습니다.

그러나 빈 테이블에 즉시 실행 된 한 번 같은 것을 명령 count(*)select top 1000에서가 SQL Management Studio지금 실행 옛날을.

SELECT COUNT(*) FROM TABLE_NAME 

0을 반환하는 데 11 분이 SELECT TOP 1000걸렸고 빈 테이블을 반환하는 데 거의 10 분이 걸렸습니다.

또한 하드 드라이브의 여유 공간이 문자 그대로 사라졌습니다 (100G에서 20G로 감소). 사이에 일어난 유일한 일은 내가 실행 한 단일 쿼리였습니다.

DELETE FROM TABLE_NAME

세계에서 무슨 일이 일어나고 있습니까?!?



답변

TRUNCATE보다 훨씬 더 빠르거나 더 나은지 에 대해 이미 알고 DELETE있지만 여전히 해결해야 할 질문이 남아 있습니다.

완료SELECT 후 왜 느려 집니까?DELETE

때문이다 DELETE에만있다 고스트 행을. 테이블은 12M 행이 있었을 때만 큼 크지 않습니다. 행 수 (0)를 계산하려면 12M 행을 계산하는 데 시간이 걸립니다. 시간이 지나면 고스트 정리 프로세스에서 이러한 고스트 레코드를 가비지 수집하고 고스트 포함 된 페이지를 할당 해제 하면 SELECT 속도가 빨라집니다. 하지만 지금 Skipped Ghosted Records/secperfmon 을 체크인하면 아마도 급증 할 것입니다 SELECT COUNT(*). 테이블을 다시 작성하여 작업 속도를 높일 수도 있습니다 ALTER TABLE ... REBUILD..

TRUNCATE 유령을 남기지 않기 때문에이 문제를 처리했을 것입니다.

저장소 엔진 내부 : 고스트 정리 심층 도 참조하십시오 .


답변

DELETEtransaction loglog sequence number (LSN)정보 를 유지 관리 할뿐 아니라 테이블의 행을 한 번에 하나씩 삭제하여의 각 행을 기록 합니다. 테이블에 거대한 데이터 (1 천 2 백만 레코드)가 있다고 언급 했으므로 삭제 후 하드 디스크 공간이 부족한 경우 데이터베이스 로그 파일의 크기를 확인하십시오. 아마 자랐을 것입니다.

더 나은 방법은 다음과 같습니다.

TRUNCATE TABLE_NAME

답변

(이것은 원래 @DaveE의 답변에 대한 주석 이었지만 시간이 오래 걸리기 때문에 자체 답변에 넣었습니다.)

TRUNCATE 기록 된 동작. 그렇지 않으면 ACID와 호환되지 않아야합니다. 그러나 차이 TRUNCATEDELETE:

  • 로그 공간 사용량 : TRUNCATE해제 된 페이지 / 연장자 * 만 DELETE기록하고 개별 행은 기록합니다.
  • 잠금 사용법 : 행 잠금을 사용 TRUNCATE하는 것과는 반대로 테이블 잠금 및 페이지 잠금을 사용하므로 일반적으로 잠금을 적게 DELETE사용합니다. **.
  • IDENTITYsequence : TRUNCATE테이블에서 ID 시퀀스를 재설정합니다 (있는 경우).

(* 익스텐트 = 8 페이지. TRUNCATE익스텐트가 모두 하나의 테이블에있는 경우 익스텐트를 기록 / 제거합니다. 그렇지 않으면 혼합 익스텐트에서 페이지를 기록 / 제거합니다.

** 이것의 한 가지 부작용 DELETE FROM TABLE은 작업이 독점 테이블 잠금을 얻을 수 있는지 여부에 따라 테이블에 빈 페이지가 할당 될 수 있다는 것입니다.)

따라서 (원래 질문으로 돌아가서), 테이블을 비우고 있지만 구조를 유지하려는 경우 (NB : 다른 테이블의 외래 키로 참조되는 테이블에서는 사용할 수 없음) TRUNCATE TABLE보다 결정적으로 좋습니다 .DELETE FROM TABLETRUNCATE

@Tullo의 의견에서 언급했듯이 데이터베이스의 복구 모델도 확인하십시오. 가득 차면 로그 백업을 시작하거나 복구 모델을 단순으로 변경해야합니다. 두 가지 중 하나를 수행하면 여유 공간을 모두 확보하기 위해 로그 파일을 일회용 작업 (NB : log file only ) 으로 축소 할 수 있습니다.

마지막으로 알아야 할 또 다른 사항은 테이블 통계입니다. 쿼리 최적화 프로그램이 이전 통계에 의해 트립되지 않도록 UPDATE STATISTICS <TABLENAME>' afterTRUNCATE /DELETE`를 실행하십시오 .


답변

(참고 : DBA가 아닙니다.) DELETE는 기록 된 작업이며 사용 된 공간을 비우지 않습니다. ‘빈’테이블 스페이스에서 실행중인 공간 및 테이블 스캔을 차지하는 큰 트랜잭션 로그가있을 수 있습니다. 트랜잭션 로그를 지우고 데이터베이스를 축소해야한다고 생각합니다. 이 StackOverflow 기사 를 시작하십시오.

나중에이 작업을 수행하려면 TRUNCATE TABLE을 사용하십시오.

편집 : TRUNCATE가 기록되지 않는다는 내 설명이 잘못되었습니다. 제거되었습니다.