A 테이블에 값을 업데이트하는데, 업데이트할 값을 B에서 가져오고 싶은 경우가 많다.

이럴 때는 WHERE COLNAME IN (SELECT ...) 와 같은 SUBQUERY 구문을 사용하지만, 다음과 같이 JOIN을 사용할 수도 있다.

UPDATE UPDATE_TAB
SET UPDATE_TAB.MANAGE = 1
FROM TEST_TAB
WHERE TEST_TAB.SEQ = UPDATE_TAB.SEQ AND TEST_TAB.MANAGE = 1

DELETE문도 마찬가지로 쓸 수 있다.
DELETE UPDATE_TAB
FROM TEST_TAB
WHERE TEST_TAB.SEQ = UPDATE_TAB.SEQ
AND TEST_TAB.MANAGE = 1


SELF JOIN도 가능할까??
위와 같은 JOIN을 같은 테이블 내에서 다음과 같이 SELF JOIN 하는 것도 가능은 한데...
UPDATE UPDATE_TAB
SET UPDATE_TAB.MANAGE = 1
FROM UPDATE_TAB, UPDATE_TAB A
WHERE A.SEQ = UPDATE_TAB.SEQ AND A.MANAGE = 1



문제는 이런 SQL이 DEADLOCK을 유발할 가능성이 높다는 것이다.
특히 SELF JOIN 하여 UPDATE하는 경우는 데드락에 대단히 취약해서... 배치로 한번 정도 사용하는 것은 괜찮겠지만, 어플리케이션 코드 안에 이런 SQL을 박아놓고 멀티스레드로 돌린다거나 하면.. DB 죽이기 십상이다. (저런 SQL로 실제 고객사의 운영DB를 죽인 적이 있다. ㅎㅎ)

만약 어플리케이션의 코드에서 저런 식의 SQL을 써야 한다면, 차라리 SELECT를 먼저하고 UPDATE를 따로 하는 것이 낫다.

만약, 이런 SQL을 반드시 사용해야 할 때는... 인덱스를 적절히 사용하여 LOCK이 걸리는 페이지를 최소화시키는 것이 중요하다. 인덱스가 있을 경우 업데이트와 관련된 레코드가 있는 페이지에만 LOCK을 걸지만 인덱스가 없으면 LOCK이 걸리는 범위가 확대되기 때문이다.

Posted by kuaaan

댓글을 달아 주세요

  1. 씨디맨 2008.08.21 09:21 신고  댓글주소  수정/삭제  댓글쓰기

    내공이 느껴지네요

  2. [SwinG] 2008.08.21 16:14 신고  댓글주소  수정/삭제  댓글쓰기

    그렇네열~
    내공이 전혀 안 느껴 지네열~
    더 열심히 하세열~

  3. [SwinG] 2008.08.21 16:15 신고  댓글주소  수정/삭제  댓글쓰기

    헛 근데 글 쓴 시간이??? 이거 컴퓨터 타임으로 시간이 기록되나?
    왜 미래의 시간으로 기록이 되었나?

    • kuaaan 2008.08.21 17:48 신고  댓글주소  수정/삭제

      예약 게시 기능으로 예약된 글을 수동으로 상태를 "공개"로 바꾸면.. 예약된 상태에서 글만 보이거던. 약간 이상스러운 상태라고 볼 수 있지. 잘 지내나? 왜 안와~~~



사랑합니다. 편안히 잠드소서