Microsoft SQL Server에서 데이터를 제거하는 방법은 크게 두 가지입니다. 바로 DELETE 문과 TRUNCATE TABLE 문입니다. 두 명령어 모두 테이블의 데이터를 삭제한다는 공통점이 있지만, 내부 동작 방식과 성능, 로그 처리 방식에서는 상당한 차이가 있습니다. 이 글에서는 두 구문의 핵심 차이점을 살펴보고, 어떤 상황에서 어떤 명령어를 사용하는 것이 적절한지 알아보겠습니다.
DELETE 문이란?
DELETE는 DML(데이터 조작 언어)에 속하는 명령어로, 테이블에서 레코드(Row)를 한 행씩 제거하는 역할을 합니다. DELETE 문으로 데이터를 삭제하면 다음과 같은 특징이 있습니다.
- 행 단위 로깅: 삭제되는 각 행이 트랜잭션 로그(Transaction Log)에 개별적으로 기록됩니다.
- 조건부 삭제 가능:
WHERE절을 사용하여 특정 조건에 맞는 데이터만 선택적으로 삭제할 수 있습니다. - 복구 가능성: 트랜잭션 로그에 모든 내역이 남기 때문에, 실수로 삭제한 데이터를 로그 기반으로 복구할 여지가 있습니다.
- 트리거 실행: DELETE 트리거가 설정된 테이블에서는 삭제 시 트리거가 함께 실행됩니다.
- IDENTITY 유지: 자동 증가(IDENTITY) 열의 값을 초기화하지 않으며, 삭제 후에도 마지막 증가 값이 그대로 유지됩니다.
- 권한 요구 사항: 해당 테이블에 대한 DELETE 권한만 있으면 되며, 테이블 소유권(ownership)은 반드시 필요하지 않습니다.
이러한 특징 덕분에 DELETE는 단일 테이블뿐 아니라 여러 관계형 테이블과 연동된 환경에서도 유연하게 활용할 수 있습니다.
DELETE 기본 문법
[ WITH <common_table_expression> [, ...n] ]
DELETE
[ TOP ( expression ) [ PERCENT ] ]
[ FROM ]
{ table_name [ WITH ( table_hint_limited [...n] ) ]
| view_name
| rowset_function_limited
| table_valued_function
}
[ FROM <table_source> [, ...n] ]
[ WHERE { <search_condition>
| { [ CURRENT OF
{ { [ GLOBAL ] cursor_name }
| cursor_variable_name
}
]
}
}
]
[ OPTION ( query_hint [, ...n] ) ]
[;]
TRUNCATE TABLE 문이란?
TRUNCATE TABLE은 테이블의 모든 데이터를 한 번에 제거하는 명령어입니다. DELETE처럼 행을 하나씩 지우는 것이 아니라, 데이터가 저장된 페이지(Page) 단위로 할당을 해제하는 방식으로 동작합니다. 주요 특징은 다음과 같습니다.
- 최소 로깅(Minimal Logging): 행 단위 로그가 아닌 페이지 할당 해제 정보만 기록되므로 처리 속도가 매우 빠릅니다.
- WHERE 절 사용 불가: 조건 없이 테이블의 전체 데이터만 삭제할 수 있습니다.
- IDENTITY 초기화: 자동 증가 열의 시드 값이 초기값으로 재설정됩니다.
- 외래 키 제약: 다른 테이블의 외래 키(Foreign Key)로 참조되고 있는 테이블에는 사용할 수 없습니다.
- 롤백 가능: 트랜잭션 내에서 실행했다면 ROLLBACK으로 되돌릴 수 있습니다.
- 권한 요구 사항: 테이블에 대한 ALTER 권한이 필요합니다.
TRUNCATE TABLE table_name;
DELETE vs TRUNCATE 핵심 차이 요약
| 구분 | DELETE | TRUNCATE |
|---|---|---|
| 명령어 분류 | DML | DDL |
| 삭제 범위 | 행 단위(조건 삭제 가능) | 테이블 전체 |
| 로그 기록 | 행별 상세 로깅 | 최소 로깅 |
| 실행 속도 | 상대적으로 느림 | 매우 빠름 |
| IDENTITY 초기화 | 유지됨 | 초기화됨 |
| 트리거 실행 | 실행됨 | 실행되지 않음 |
| 필요 권한 | DELETE 권한 | ALTER 권한 |
어떤 상황에서 무엇을 사용해야 할까?
특정 조건의 데이터만 골라서 지우거나, 삭제 이력을 로그로 남겨야 하거나, 트리거 로직을 실행해야 한다면 DELETE가 적합합니다. 반면, 테스트 데이터를 한꺼번에 비우거나 대용량 테이블을 신속하게 초기화해야 하는 경우에는 TRUNCATE TABLE이 성능 면에서 훨씬 유리합니다. 다만 외래 키로 참조 중인 테이블이라면 TRUNCATE를 사용할 수 없으므로 DELETE를 사용해야 한다는 점을 꼭 기억하세요.