공공부하자개발 · 영어 학습 노트
SQL
대용량·배치실행 계획·조인·인덱스·파티션·락·대량 처리0/8 완료
  • 01실행 계획 읽기
  • 02조인 방식: Nested Loop, Hash, Sort Merge 와 드라이빙 테이블
  • 03인덱스 튜닝
  • 04통계 정보와 힌트
  • 05파티션: 범위·목록·해시 분할, 파티션 프루닝, 파티션 단위 관리
  • 06대량 INSERT·UPDATE 와 배치 커밋
  • 07락과 데드락
  • 08대용량 삭제·아카이빙
사이트 소개개인정보처리방침연락처
© 2026 공부하자
홈 › 대용량·배치 › 08 / 8

대용량 삭제·아카이빙

나눠서 삭제, 남길 것만 옮기기, 보관 테이블
섹션 6진행 0 / 8
1왜 배우는가2핵심 원리3코드 예제4응용 변형 예제5자주 하는 실수 (Tip)6정리‹ 이전다음 ›

2. 핵심 원리

2.1 한 번에 큰 DELETE 가 문제인 이유

DELETE 는 지우는 행마다 되돌리기 위한 언두 정보와 복구를 위한 로그를 남깁니다. 지울 행이 많을수록 이 기록이 커지고, 커밋하기 전까지 그 행들의 잠금이 유지됩니다. 실패하거나 취소하면 남긴 기록을 되돌려야 하므로 롤백도 오래 걸립니다.

문제 한 번에 큰 DELETE 나눠서 삭제
언두·로그 전체 분량이 한꺼번에 쌓임 청크 크기만큼만 쌓이고 커밋 뒤 정리됨
잠금 끝날 때까지 전체 행 잠금 청크 동안만 잠금 (대용량 07 락)
실패 시 전부 롤백, 오래 걸림 마지막 청크만 롤백, 앞은 남음
진행 확인 끝나야 알 수 있음 청크마다 남은 건수 확인

2.2 나눠서 삭제하는 흐름

흐름은 대용량 06 대량 처리의 청크 처리와 같습니다. 기준일 이전 행 중 N건을 지우고 커밋하고, 남은 대상이 0건이 될 때까지 되풀이합니다. 남은 대상이 청크 크기보다 적으면 있는 만큼만 지우고 끝납니다.

N건만 지우는 문법은 DB 마다 다릅니다.

DB N건만 삭제
Oracle · Tibero WHERE ROWNUM <= n, 또는 키 범위
MySQL DELETE ... LIMIT n (단일 표 DELETE 에서만)
MSSQL DELETE TOP (n)
표준 문법 서브쿼리에서 FETCH FIRST n ROWS ONLY (MySQL 불가)

키 범위(id > a AND id <= b)로 나누면 DB 와 상관없이 같은 문장이고, 청크가 끝날 때 마지막 키를 기록하면 재시작도 쉽습니다.

핵심

삭제 조건 컬럼(날짜)에는 인덱스가 있어야 합니다. 인덱스가 없으면 청크마다 표 전체를 훑어서, 청크가 100번이면 전체 읽기도 100번 일어납니다.

2.3 삭제해도 공간은 바로 줄지 않는다

행을 지워도 그 행이 차지하던 공간은 운영체제에 바로 돌아가지 않고 표 안의 빈 공간으로 남습니다. 새 행이 들어오면 재사용하지만, 표가 더 이상 커지지 않는다면 그대로 남습니다. DB 별로 공간을 정리하는 방법이 다릅니다.

DB 삭제 뒤 상태 공간 정리
Oracle 최고 수위(HWM)가 그대로라 전체 읽기가 빈 블록까지 훑음 SHRINK SPACE (10g 부터, ENABLE ROW MOVEMENT 필요) 또는 MOVE (인덱스 재생성 필요)
MySQL InnoDB 파일 크기가 줄지 않음 OPTIMIZE TABLE (표 재구성)
MSSQL 빈 페이지가 남고 조각화 인덱스 REBUILD. 파일 축소(DBCC SHRINKFILE)는 조각화를 부르므로 신중히

정리 작업은 표를 다시 쓰거나 잠그는 무거운 작업이라 삭제와 별개로 점검 시간에 계획해서 합니다.

2.4 보관 이동은 한 묶음으로

지운 데이터를 나중에 확인해야 하면 보관 표(log_archive)로 옮긴 뒤 지웁니다. 안전하게 하려면 세 가지를 지킵니다.

  1. INSERT 와 DELETE 는 같은 키 집합에 같은 조건으로 실행합니다.
  2. 둘을 같은 트랜잭션에 두고, 복사된 건수와 지울 건수가 맞는지 확인한 뒤 커밋합니다.
  3. 끝나면 원본과 보관 표의 합계가 이동 전과 같은지 대사합니다.

INSERT 를 커밋하고 나서 DELETE 하면, 그 사이에 실패했을 때 같은 행이 양쪽에 남습니다. 반대로 DELETE 를 먼저 커밋하면 실패했을 때 행이 사라집니다. 실무 09 이관·검증의 대사 방식을 그대로 씁니다.

2.5 남길 것만 옮기고 바꿔치기

지울 행이 대부분이고 남길 행이 소수라면 지우는 것보다 남길 행만 새 표로 복사하는 쪽이 빠릅니다. 큰 삭제는 행마다 로그를 남기지만, 새 표에 넣는 일은 남길 행만 쓰기 때문입니다.

단계 내용
1 남길 행만 새 표로 복사 (CTAS 또는 CREATE 후 INSERT ... SELECT)
2 새 표에 PK·인덱스·제약을 다시 만든다
3 이름 바꾸기: 원본을 옛 이름으로, 새 표를 원래 이름으로
4 건수 확인 후 옛 표 DROP

주의할 점도 있습니다. CREATE TABLE AS SELECT 는 데이터만 복사하므로 인덱스·PK·FK·권한·트리거는 직접 다시 만들어야 합니다. 작업하는 동안 원본에 들어오는 쓰기를 막아야 하고, 그렇지 않으면 복사한 뒤 들어온 행이 바꿔치기와 함께 사라집니다. 옛 표를 참조하는 뷰·프로시저도 점검해야 합니다.

2.6 삭제 방법 고르기

상황 방법
표 전체를 비운다 TRUNCATE (FK 로 참조되는 표는 불가, Oracle·MySQL 은 롤백 불가, MSSQL 은 트랜잭션 안에서 가능)
일부만 지우고 나머지가 훨씬 많다 나눠서 삭제
지울 양이 대부분이다 남길 행만 새 표로 옮기고 바꿔치기
날짜 기준으로 정기적으로 지운다 파티션으로 설계해서 조각을 떼어 냄 (대용량 05 파티션)
지운 뒤에도 봐야 한다 보관 표로 이동 후 삭제
핵심 원리
  • 2.1 한 번에 큰 DELETE 가 문제인 이유
  • 2.2 나눠서 삭제하는 흐름
  • 2.3 삭제해도 공간은 바로 줄지 않는다
  • 2.4 보관 이동은 한 묶음으로
  • 2.5 남길 것만 옮기고 바꿔치기
  • 2.6 삭제 방법 고르기
이전 섹션1 왜 배우는가2 / 6다음 섹션3 코드 예제