얼마전 회사에서 DB의 데이터를 보정(update)하는 작업에서 문제를 겪었던 경험에 대해 얘기해보려고 합니다.
A테이블의 c값들을 csv파일의 값으로 보정하는 일이였습니다. 이를 위해 csv파일을 토대로 B라는 임시 테이블을 생성했습니다.
개발자는 DDL권한이 없어 직접 생성하지는 못하고 DBA 분에게 테이블 생성을 요청했습니다.
이해를 돕기 위해 간략하게 테이블을 정의해 보겠습니다.
CREATE TABLE A (
a varchar(20) primary key,
b varchar(20),
c varchar(20)
);
CREATE TABLE B (
c varchar(20),
d varchar(20)
);
다음과 같은 간단한 update쿼리를 만들고 실행했습니다.
UPDATE A
JOIN B ON A.c = B.c
SET A.b = CONCAT("PREFIX",B.d);
하지만 아무리 시간이 지나도 쿼리가 완료되지 않았습니다.
Full Table Scan으로 쿼리가 실행됐기 때문입니다. B테이블에는 index자체가 존재하지 않았고, A테이블에는 pk가 존재했지만 pk를 전혀 활용하지 못하고 있었습니다.
A테이블에는 약 17만건의 데이터가, B테이블에는 약 1만3천건의 데이터가 들어있어 full table scan을 실행했을 때 170_000 x 13_000 = 2_210_000_000의 탐색이 필요한 상황인거죠.

UPDATE A
JOIN B ON A.a = B.a // B.a는 존재하지 않음
SET A.b = CONCAT("PREFIX",B.d);
CREATE TABLE B (
c varchar(20),
d varchar(20)
);
CREATE INDEX idx_b_c ON B(c);
테이블을 직접 온전하게 제어할 수 있었다면 위 두 가지 방법을 적절히 사용할 수 있었겠지만 그러지 못한 상황에서 다음과 같은 방법으로 문제를 해결했습니다.
SELECT
A.a, B.d
FROM
A JOIN B ON A.c = B.c;
UPDATE A
JOIN B ON A.a = B.a
SET A.b = CONCAT("PREFIX",B.d);
다음날 사수님에게 이런 일이 있었다고 말씀드렸고 같이 커피를 마시며 간단히 얘기를 나눴습니다.
정말 감사하게도 고생했고 본인이 꼼꼼히 챙기지 못해서 미안하다고 말씀해 주셨습니다.
또한 문제가 발생했을 때 당연히 당황스럽겠지만 그럼에도 침착하게 대처하는게 좋을거 같다고 조언해 주셨습니다. 실제로 문제 해결 당시 저는 뭘 어떻게 해야 할지 몰라 당황하고 있었고, TPM님과 팀장님께서 도와주셔서 문제를 해결할 수 있었습니다.
이번 일을 경험삼아 부족한 부분을 보완하고 앞으로 더 잘해야 겠다는 생각이 들었습니다.