DB

[MySQL] DELETE + EXISTS / IN 조건으로 정밀하고 안전하게 데이터 삭제하기 ✂️

인생아 2025. 7. 2. 17:51
반응형

MySQL에서 데이터를 삭제할 때는 DELETE 문 하나만으로는 부족한 경우가 많다. 특히 조건이 다른 테이블과 연관된 경우, 보다 정밀한 제어가 필요하다.
이럴 때 자주 사용되는 조건절이 바로 EXISTS와 IN이다. 두 조건은 서브쿼리와 함께 사용되어 특정 조건을 만족하는 데이터만 삭제할 수 있도록 해준다.

✅ DELETE + IN 조건 기본 문법

DELETE FROM 테이블명
WHERE 컬럼명 IN (
  SELECT 컬럼명 FROM 다른_테이블 WHERE 조건
);

IN 서브쿼리는 서브쿼리의 결과에 포함된 값들과 일치하는 레코드만 삭제한다.

예제 1️⃣: 탈퇴한 유저의 게시글 삭제

DELETE FROM posts
WHERE user_id IN (
  SELECT id FROM users WHERE status = '탈퇴'
);

이 쿼리는 users 테이블에서 '탈퇴' 상태인 사용자 ID를 찾아, 그에 해당하는 posts를 삭제한다.
IN 조건은 간결하지만 서브쿼리 결과에 NULL이 있으면 의도치 않은 결과가 나올 수 있으므로 주의가 필요하다.

반응형

✅ DELETE + EXISTS 조건 기본 문법

DELETE FROM 테이블명 별칭
WHERE EXISTS (
  SELECT 1 FROM 다른_테이블 WHERE 조건 AND 관계_조건
);

EXISTS는 서브쿼리에서 행이 존재하면 TRUE로 간주하여 삭제를 수행한다. 성능 상 이점이 있는 경우도 많다.

예제 2️⃣: 정지된 계정의 세션 삭제

DELETE FROM sessions s
WHERE EXISTS (
  SELECT 1 FROM users u WHERE u.id = s.user_id AND u.status = '정지'
);

EXISTS는 IN보다 더 관계 기반 조건 확인에 적합하며, 특히 대규모 테이블에서 더 빠르게 작동하는 경우가 많다.

✅ DELETE + NOT EXISTS 사용 예시

DELETE FROM logs l
WHERE NOT EXISTS (
  SELECT 1 FROM users u WHERE u.id = l.user_id
);

존재하지 않는 사용자(users)의 로그(logs)만 삭제한다.
이 패턴은 고아 레코드(Ghost Record) 정리에 자주 활용된다.

반응형

✅ EXISTS vs IN 차이점 비교 🤔

항목 IN EXISTS
작동 방식 서브쿼리 결과 목록에 포함되면 TRUE 서브쿼리가 조건을 만족하는 레코드가 존재하면 TRUE
성능 소규모에서는 빠름, 대규모에서는 느릴 수 있음 대규모 데이터에서 유리한 경우 많음
NULL 처리 NULL이 포함되면 문제 발생 가능 영향 없음
대표 활용 ID 비교, 간단한 조건 관계 조건, 존재 여부 확인

요약하자면:

  • 비교 대상이 많고 서브쿼리 결과가 작으면 IN
  • 조건이 복잡하거나 대상이 크면 EXISTS를 사용하는 것이 좋다

✅ 실무에서 자주 쓰이는 활용 예

  • 탈퇴한 유저의 게시글, 댓글, 세션, 주문 정보 삭제
  • 일정 기간 경과한 데이터 중 관련 항목이 없는 레코드 정리
  • FK 제약조건으로 인해 직접 삭제할 수 없는 데이터 필터링 후 정리

✅ 인덱스 최적화 팁 🔧

IN과 EXISTS에서 참조하는 컬럼(예: user_id, order_id)에는 반드시 인덱스가 존재해야 한다.
인덱스가 없으면 서브쿼리마다 전체 테이블 스캔이 발생하므로 성능 저하의 원인이 된다.

✅ 공식 문서 참고 링크

반응형