대규모 레코드 일괄 삭제 방법
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
데이터 분석
대상자
- 데이터베이스 개발자, DevOps 엔지니어
- 중간~고급 수준 (SQL 성능 최적화, 락 관리, 인덱스 활용 지식 필요)
핵심 요약
- 일반적인 일괄 삭제 방식은 락 유지 시간을 길어져서 동시성 문제 발생
- 클러스터 인덱스와 진행 상태 추적을 활용한 최적화 방법으로 로직 읽기 횟수 60% 감소
OnlineSalesKey
인덱스 활용 시 각 배치별 로직 읽기 6,363회 이하로 제한
섹션별 세부 요약
1. 문제 정의: 일반적인 일괄 삭제의 한계
- 단일
DELETE
명령어 실행 시 46,650회 로직 읽기 발생 - 1,000건 단위 일괄 삭제 시 총 1,486,285회 로직 읽기 발생
- 인덱스 스캔 반복으로 마지막 배치 시 전체 테이블 스캔 발생
2. 메트릭 정의: 성능 평가 기준
- 로직 읽기 횟수 대신 쿼리 실행 시간 측정
- 로직 읽기 횟수와 실행 시간 간 상관관계 강함
3. 최적화 방법: 인덱스 기반 진행 추적
OnlineSalesKey
인덱스 활용하여 이전 처리 레코드 기준 설정@LargestKeyProcessed
변수로 다음 배치 범위 결정TOP(1000)
+ORDER BY
로 인덱스 스캔 최소화
4. 성능 비교: 일반 vs 최적화 방법
- 일반 일괄 삭제: 1,486,285회 로직 읽기, n² 복잡도
- 최적화 방법: 46,796회 로직 읽기, n 복잡도
- 락 유지 시간 동일하지만, 각 배치별 로직 읽기 횟수 극감
결론
- 인덱스 기반 진행 추적(
OnlineSalesKey
활용)으로 일괄 삭제 성능 90% 개선 DELETE TOP (1000)
대신WHERE OnlineSalesKey > @LargestKeyProcessed
조건 사용 권장- 성능 테스트 필수: n² 복잡도 방식은 동시성 문제 유발 가능성 높음
-- 최적화된 일괄 삭제 예시
DECLARE @LargestKeyProcessed INT = -1, @NextBatchMax INT, @RC INT = 1;
WHILE (@RC > 0)
BEGIN
SELECT TOP (1000) @NextBatchMax = OnlineSalesKey
FROM FactOnlineSales
WHERE OnlineSalesKey > @LargestKeyProcessed AND CustomerKey = 19036
ORDER BY OnlineSalesKey ASC;
DELETE FactOnlineSales
WHERE CustomerKey = 19036 AND OnlineSalesKey > @LargestKeyProcessed AND OnlineSalesKey <= @NextBatchMax;
SET @RC = @@ROWCOUNT;
SET @LargestKeyProcessed = @NextBatchMax;
END