홈 › 대용량·배치 › 08 / 8

대용량 삭제·아카이빙

나눠서 삭제, 남길 것만 옮기기, 보관 테이블
섹션 6진행 0 / 8

4. 응용 변형 예제

예제 6: DB별 청크 삭제 문법 (문법 검토만)

N건만 지우는 문법을 DB 별로 정리합니다. 아래 문장은 H2 로 실행하지 않았고 문법 검토만 했습니다.

sql
-- Oracle · Tibero
DELETE FROM log_hist
 WHERE log_date < DATE '2026-01-01'
   AND ROWNUM <= 1000;
COMMIT;
sql
-- MySQL: 단일 표 DELETE 에서만 LIMIT 사용 가능
DELETE FROM log_hist
 WHERE log_date < '2026-01-01'
 ORDER BY id
 LIMIT 1000;
sql
-- MSSQL
DELETE TOP (1000) FROM log_hist
 WHERE log_date < '2026-01-01';

MySQL 의 DELETE ... LIMIT 은 조인이 있는 다중 표 DELETE 에는 쓸 수 없습니다. MSSQL 의 DELETE TOP 은 어떤 행이 지워지는지 순서를 정해 주지 않으므로, 순서가 중요하면 키를 골라 조인하거나 키 범위로 나눕니다. 세 DB 모두 되풀이하다가 삭제된 행 수가 0 이 되면 종료합니다.

예제 7: MSSQL 은 OUTPUT 으로 이동을 한 문장에 (문법 검토만)

MSSQL 은 DELETE 가 지운 행을 OUTPUT deleted.* 로 바로 다른 표에 넣을 수 있어서, 복사와 삭제가 한 문장으로 끝납니다. 한 문장은 원자적이므로 INSERT 와 DELETE 의 키 집합이 어긋날 수 없습니다. H2 는 이 문법이 없어 실행하지 않았습니다.

sql
-- MSSQL: H2 미지원, 문법 검토만
DELETE TOP (1000) FROM log_hist
OUTPUT deleted.id, deleted.log_date, deleted.user_id, deleted.msg, GETDATE()
  INTO log_archive (id, log_date, user_id, msg, archived_at)
 WHERE log_date < '2026-01-01';

Oracle·MySQL 은 이런 문법이 없어 예제 4 처럼 같은 키 범위로 INSERT 와 DELETE 를 나눠 쓰고 같은 트랜잭션으로 묶습니다.

예제 8: 삭제 뒤 공간 회수 (문법 검토만)

아래는 DB 별 공간 회수 문장입니다. H2 로 실행하지 않았고 효과도 측정하지 않았습니다.

sql
-- Oracle: 행 이동을 허용한 뒤 축소 (10g 부터)
ALTER TABLE log_hist ENABLE ROW MOVEMENT;
ALTER TABLE log_hist SHRINK SPACE;
-- 또는 표를 다시 쓴다 (이 뒤 인덱스는 UNUSABLE 이 되어 재생성 필요)
ALTER TABLE log_hist MOVE;
sql
-- MySQL InnoDB: 표를 재구성해 파일 크기를 줄인다
OPTIMIZE TABLE log_hist;
sql
-- MSSQL: 인덱스 재구성으로 정리 (파일 축소는 조각화를 부르므로 신중히)
ALTER INDEX ALL ON log_hist REBUILD;

정리 작업은 표를 잠그거나 많은 I/O 를 쓰므로 운영 시간을 피해 실행합니다. 정기적으로 날짜 기준 삭제를 한다면 파티션으로 설계해서 오래된 조각을 통째로 떼어 내는 편이 가장 가볍습니다(대용량 05 파티션).