SQL에서 대량의 데이터를 처리하는 것은 메모리 오버플로우, 잠금 및 안정적인 성능 보장을 방지하기 위한 특별한 접근이 필요합니다. 주요 방법 중 하나는 작업을 배치로 나누는 것입니다: 입력 데이터는 작은 단위로 처리되어 서버의 부하를 줄이고 트랜잭션과 오류 발생 시 롤백을 더 잘 관리할 수 있게 됩니다.
주요 점:
ROWCOUNT 또는 LIMIT / TOP)COMMIT하여 트랜잭션 로그를 해제예시 (SQL Server):
DECLARE @BatchSize INT = 1000; WHILE 1 = 1 BEGIN BEGIN TRANSACTION; DELETE TOP(@BatchSize) FROM BigLogTable WHERE CreatedDate < '2021-01-01'; IF @@ROWCOUNT = 0 BREAK; COMMIT TRANSACTION; END
성능에 미치는 영향을 최소화하면서 대형 테이블에서 1억 개의 레코드를 어떻게 삭제합니까?
부정확한 답변: "하나의 큰 DELETE 수행".
정확한 답변: 배치 크기를 제어하여 부분적으로 삭제하고 각 블록 후에는 COMMIT을 수행하며 필요한 경우 디스크 부하와 잠금을 줄이기 위해 지연(WAITFOR DELAY 또는 유사한 방법)을 사용합니다.
예시 (PostgreSQL):
DO $$ BEGIN LOOP DELETE FROM big_table WHERE created_at < NOW() - interval '1 year' LIMIT 10000; EXIT WHEN NOT FOUND; COMMIT; END LOOP; END$$;
이야기
프로젝트: 고부하 은행 서비스. 오류: 개발자가 8천만 행을 포함한 오래된 로그를 단일 큰 쿼리로 삭제했습니다. 결과 — 트랜잭션 로그가 테라바이트로 증가하고, 사용 가능한 디스크 공간이 모두 소진되어 서비스가 "중단"되었습니다.
이야기
프로젝트: 재고 관리 시스템을 갖춘 인터넷 쇼핑몰. 오류: 대량 삽입 시 트랜잭션 크기를 제한하지 않았습니다. 대량의 배치를 가져오는 과정에서 레코드 오류가 발생하여 이전 작업을 롤백하고 다시 수행해야 했고, 이는 몇 시간이 아닌 몇 분이 걸리게 되었습니다.
이야기
프로젝트: 리테일러, 주문 세부 내역을 포함한 보고 데이터베이스. 오류: 배치를 사용했지만 반복 간의 COMMIT을 잊어버렸습니다 — 트랜잭션 로그가 기하급수적으로 증가하고, 서버가 "느려지기" 시작했으며, 결국 긴급 로그 정리가 필요했습니다.