UPDATE / DELETE
UPDATE
/ DELETE
쿼리를 단일 테이블에 대해 한 건(또는 소량) 뿐만 아니라, 조인을 통해 여러 테이블을 동시에 대상으로 하여 UPDATE
/ DELETE
쿼리를 실행할 수 있다.
UPDATE(DELETE) ... ORDER BY ... LIMIT n
일반적으로 WHERE
조건에 일치하는 모든 레코드를 처리하지만, ORDER BY
+ LIMIT
조합을 사용하면 상위 n개의 레코드만 처리할 수 있다.
-- 오래된 로그를 1,000건씩 안전하게 삭제
DELETE
FROM event_logs
WHERE event_date < '2024-01-01'
ORDER BY event_date
LIMIT 1000;
장시간 잠금(Lock)으로 인한 다른 트랜잭션 영향 최소화
운영 환경에서 점진적 데이터 정리 가능
배치 단위 처리에 자주 사용
JOIN UPDATE
두 개 이상의 테이블을 조인해, 조인된 결과를 대상으로 UPDATE / DELETE를 실행하는 기능으로, 주로 다음과 같은 경우에 사용한다.
한쪽 테이블의 값을 다른 테이블의 컬럼에 반영해야 하는 경우
양쪽 테이블에 공통으로 존재하는 레코드만 찾아 갱신해야 하는 경우
-- Sales 부서에 속한 직원들의 급여를 5,000씩 인상
UPDATE employees e
INNER JOIN departments d ON e.dept_id = d.dept_id
SET e.salary = e.salary + 5000
WHERE d.dept_name = 'Sales';
JOIN 순서에 따라 성능이 달라질 수 있으므로, 실행 계획(Execution Plan) 확인
읽기 전용 테이블도 읽기 잠금(Read Lock), 갱신 대상 테이블은 쓰기 잠금(Write Lock)이 걸리므로, 웹 서비스 환경에서는 데드락 가능성에 주의
여러 레코드 UPDATE
8.0부터는 Row Constructor를 이용해 각 레코드에 서로 다른 값을 한 번에 적용할 수 있다.(MySQL 5.7 이하 버전은 동일한 값으로만 업데이트 가능)
-- 1번 사용자의 레벨을 1 증가, 2번 사용자의 레벨을 4 증가
UPDATE user_level ul
INNER JOIN
(VALUES ROW (1, 1), ROW (2, 4)) new_user_level (user_id, level_increase)
ON new_user_level.user_id = ul.user_id
SET ul.user_lv = ul.user_lv + new_user_level.level_increase;
VALUES ROW(...)
구문은 임시 테이블을 생성하는 효과이를 기존 테이블과 조인하여 각 레코드를 선택적으로 업데이트하는 방식
다수의 UPDATE를 개별로 실행하는 것보다 네트워크/트랜잭션 오버헤드 절감
JOIN DELETE
JOIN DELETE 문장은 일반적인 단일 테이블 DELETE와 달리, 삭제 대상 테이블을 DELETE 키워드 뒤에 직접 명시해야 한다.
-- 3개 테이블 조인 후 employees, dept_emp만 삭제
DELETE e, de
FROM employees e
INNER JOIN dept_emp de ON e.emp_no = de.emp_no
INNER JOIN departments d ON de.dept_no = d.dept_no
WHERE d.dept_no = 'd59';
JOIN 순서에 따라 성능이 달라질 수 있으므로, 실행 계획(Execution Plan) 확인
여러 테이블을 동시에 삭제할 수 있으므로 관계 데이터 정리 유용
참고자료
Last updated
Was this helpful?