MySQL에서 DELETE 문은 단순해 보이지만, 실무에서는 종종 삭제가 되지 않는 문제가 발생한다.
“쿼리는 정상인데 삭제가 안돼요”, “에러는 없는데 왜 남아있죠?”와 같은 상황은 의외로 자주 발생한다.
❌ 1. WHERE 조건이 잘못되었을 때
MySQL에서 가장 흔한 DELETE 실패 원인은 WHERE 조건이 너무 좁거나 틀린 경우이다.
조건에 맞는 행이 없으면 당연히 아무 것도 삭제되지 않는다.
예제
DELETE FROM users WHERE email = 'abc@example.com';
이메일이 정확히 매치되지 않으면 삭제가 되지 않는다.
해결법
- 먼저 SELECT로 결과를 미리 확인한다
SELECT * FROM users WHERE email = 'abc@example.com';
- 값이 없으면 오타 또는 문자열 비교 문제일 수 있다
🔒 2. 외래 키(Foreign Key) 제약 조건 위반
MySQL에서 InnoDB 엔진은 기본적으로 외래 키 제약 조건을 강제한다.
삭제하려는 레코드가 다른 테이블의 외래 키로 참조되고 있다면, DELETE는 실패한다.
예제
DELETE FROM users WHERE id = 10;
→ 그런데 orders 테이블에서 user_id=10을 참조하고 있다면 삭제되지 않는다.
해결법
- 참조하고 있는 레코드를 먼저 삭제해야 한다
- 또는 외래 키에 ON DELETE CASCADE 옵션을 미리 설정해두자
ALTER TABLE orders
ADD CONSTRAINT fk_user
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE;
🧱 3. 트랜잭션 롤백 또는 커밋 누락
START TRANSACTION으로 묶은 작업 중 DELETE가 수행됐지만 COMMIT을 하지 않으면 실제 삭제는 적용되지 않는다.
예제
START TRANSACTION;
DELETE FROM logs WHERE level = 'DEBUG';
-- COMMIT을 안 하면 무효
해결법
- COMMIT을 반드시 수행해야 실제 삭제된다
COMMIT;
- 또는 ROLLBACK이 발생했는지 확인한다
📋 4. DELETE 권한 부족
사용자가 해당 테이블에 대한 DELETE 권한이 없다면 삭제가 실패한다.
특히 RDS나 공유 서버에서 많이 발생하는 문제이다.
확인 방법
SHOW GRANTS FOR 'username'@'localhost';
해결법
- DBA에게 DELETE 권한 부여 요청
GRANT DELETE ON db_name.table_name TO 'username'@'localhost';
🧪 5. 트리거(Trigger) 오류로 인한 실패
테이블에 AFTER DELETE 트리거가 설정돼 있는데 내부 로직에서 에러가 발생하면 전체 DELETE가 실패할 수 있다.
해결법
- 트리거 내용을 점검하거나 임시로 비활성화하여 테스트한다
- 로그를 확인해 트리거 에러 메시지를 확인한다
🧭 6. 조건에 NULL이 포함된 경우
WHERE column = NULL은 항상 FALSE가 되어 삭제가 되지 않는다.
NULL 비교는 반드시 IS NULL을 사용해야 한다.
예제 (잘못된 방법)
DELETE FROM users WHERE email = NULL;
올바른 방법
DELETE FROM users WHERE email IS NULL;
📌 7. 테이블이 LOCK 걸려 있는 경우
다른 트랜잭션에서 테이블이 LOCK 되어 있다면 DELETE 문이 대기하거나 실패한다.
해결법
- SHOW PROCESSLIST; 명령으로 대기 중인 트랜잭션을 확인한다
- SHOW ENGINE INNODB STATUS;로 락 정보도 확인 가능하다
🧠 추가 팁: DELETE 전에 반드시 SELECT로 확인
SELECT COUNT(*) FROM 테이블명 WHERE 조건;
삭제 대상이 맞는지 반드시 확인 후 DELETE를 실행해야 한다.
실수 방지를 위한 가장 확실한 전략이다.
🔗 공식 문서 링크
'DB' 카테고리의 다른 글
[MySQL] WITH CTE로 INSERT / UPDATE / DELETE 처리하는 실전 예제 모음 (0) | 2025.07.03 |
---|---|
[MySQL] VIEW를 통한 INSERT / UPDATE / DELETE 사용법 완전정복 (0) | 2025.07.03 |
[MySQL] CALL 프로시저 내 DML 실행 완전 정복 가이드 ⚙️ (0) | 2025.07.03 |
[MySQL] LOAD DATA INFILE로 대용량 데이터 빠르게 삽입하는 방법 ⚡ (0) | 2025.07.03 |
[MySQL] DELETE + JSON 조건으로 JSON 데이터 기반 삭제 처리하기 (0) | 2025.07.02 |
[MySQL] DELETE + NULL 조건으로 누락 데이터 정리하기 🧹 (0) | 2025.07.02 |
[MySQL] DELETE + 트랜잭션 처리로 안전한 데이터 삭제 구현하기 🔐 (0) | 2025.07.02 |
[MySQL] DELETE + EXISTS / IN 조건으로 정밀하고 안전하게 데이터 삭제하기 ✂️ (0) | 2025.07.02 |