TECH/sql

[SQL] 대량 데이터 삭제 가이드: DELETE vs TRUNCATE vs DROP 완벽 비교

런코리치 2026. 3. 5. 08:00

수백만 건, 수천만 건의 데이터를 삭제할 때 어떤 명령어를 사용하시나요? 단순히 "데이터를 지운다"는 결과는 같을지 몰라도, 그 내부에서 발생하는 일과 DB에 가해지는 부하는 천차만별입니다. 상황에 맞는 최적의 삭제 방식을 선택하기 위해 각 명령어의 특징을 파헤쳐 보겠습니다.


1. 명령어별 핵심 요약 및 비교

먼저 바쁜 분들을 위해 세 가지 방식의 차이점을 표로 정리했습니다.

구분 DELETE TRUNCATE DROP
명령어 성격 DML (Data Manipulation) DDL (Data Definition) DDL (Data Definition)
삭제 단위 행(Row) 단위 테이블 전체 (공간 초기화) 테이블 자체를 삭제
로그 발생량 많음 (행당 로그 기록) 적음 (페이지 단위 기록) 거의 없음
속도 느림 빠름 가장 빠름
Rollback 가능 불가능 (자동 커밋) 불가능 (자동 커밋)
조건(WHERE) 사용 가능 사용 불가능 사용 불가능

 


2. DELETE: 신중하고 섬세한 삭제

DELETE는 데이터 조작어(DML)입니다. 테이블의 틀은 그대로 두고 내부의 레코드를 하나씩 지우는 방식입니다.

  • 동작 원리: 각 행을 삭제할 때마다 해당 데이터를 Undo 로그Redo 로그에 기록합니다. 이는 사용자가 실수했을 때 ROLLBACK을 하기 위함입니다.
  • 리소스 부하: 만약 1,000만 건의 데이터를 DELETE하면, 1,000만 번의 로그 기록이 발생합니다. 이 과정에서 CPU와 I/O 사용량이 급증하며, 로그 파일(Transaction Log)이 가득 차서 DB가 중단될 수도 있습니다.
  • HWM(High Water Mark): 데이터를 지워도 테이블이 차지하고 있던 물리적인 공간(High Water Mark)은 줄어들지 않습니다. 즉, 데이터를 다 지워도 테이블 크기는 그대로 유지됩니다.

3. TRUNCATE: 테이블 초기화 (공장 초기화)

TRUNCATE는 데이터 정의어(DDL)입니다. 테이블의 모든 데이터를 한 번에 비우고, 사용했던 저장 공간까지 반납합니다.

  • 동작 원리: 행 단위로 지우는 것이 아니라, 테이블이 데이터를 담고 있던 데이터 페이지(Data Page) 자체를 해제해 버립니다.
  • 로그 최소화: 삭제된 행 하나하나를 기록하지 않고, "어떤 페이지가 해제되었다"는 정도의 최소한의 로그만 남깁니다. 그래서 DELETE보다 수십 배 이상 빠릅니다.
  • 공간 회수: 테이블의 용량이 다시 0에 가깝게 줄어듭니다. 새로 데이터를 넣으면 초기 상태부터 다시 쌓이게 됩니다.

4. DROP: 존재 자체를 삭제

DROP 역시 DDL이며, 데이터뿐만 아니라 테이블의 구조(스키마)와 정의 자체를 데이터 사전(Data Dictionary)에서 삭제합니다.

  • 동작 원리: 테이블에 할당된 모든 공간을 즉시 해제하고, 해당 테이블과 관련된 인덱스, 제약 조건까지 모두 삭제합니다.
  • 결과: 명령 실행 후에는 해당 테이블을 조회(SELECT)할 수조차 없습니다. 복구하려면 백업본을 가져와야만 합니다.

5. 실무에서의 상황별 선택 가이드

💡 특정 조건의 데이터만 지워야 할 때

고민할 것 없이 DELETE를 써야 합니다. 하지만 데이터가 너무 많다면 WHERE 절에 인덱스가 걸려 있는지 확인하고, Batch 단위(예: 1만 건씩 나누어서)로 삭제하는 것이 안전합니다.

💡 전체 데이터를 지우고 테이블 구조만 남길 때

로그 데이터 정리나 초기화가 목적이라면 TRUNCATE가 압도적으로 유리합니다. 하지만 FOREIGN KEY 제약 조건이 걸려 있는 경우 실행이 제한될 수 있으니 주의해야 합니다.

💡 테이블을 새로 만들어야 하거나 아예 안 쓸 때

망설임 없이 DROP을 사용하세요.


🏁 성능 최적화 팁: 대량 데이터 삭제 시 주의사항

  1. 트랜잭션 로그 관리: DELETE 실행 전, 로그 파일 용량이 충분한지 확인하세요.
  2. 인덱스 오버헤드: DELETE 시 해당 테이블에 인덱스가 많으면 각 행을 지울 때마다 인덱스 구조도 재배치해야 하므로 성능이 매우 떨어집니다. 대량 삭제 전에는 잠시 인덱스를 비활성화(Disable) 하는 것도 방법입니다.
  3. 테이블 재생성 전략 (CTAS): 수천만 건 중 일부(예: 10%)만 남기고 다 지워야 한다면, 차라리 남길 데이터만 새 테이블에 복사(CREATE TABLE AS SELECT)한 뒤 기존 테이블을 DROP하는 것이 훨씬 빠를 수 있습니다.