데이터 보정 작업 회고

최창효·2024년 6월 8일
post-thumbnail

상황 설명

얼마전 회사에서 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)
);
  • A테이블과 B테이블의 공통 속성은 c밖에 없습니다.
  • A테이블의 b값을 B테이블의 d값으로 보정해야 합니다.
  • B테이블은 인덱스가 존재하지 않습니다.

다음과 같은 간단한 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의 탐색이 필요한 상황인거죠.

어떻게 해결할 수 있을까?

1. A테이블의 pk인덱스를 활용하기

UPDATE A
JOIN B ON A.a = B.a // B.a는 존재하지 않음
SET A.b = CONCAT("PREFIX",B.d);
  • A테이블의 primary key를 활용할 수 있다면 log2(170_000) * 13_000으로 탐색을 줄일 수 있습니다.
  • 하지만 B테이블에는 A테이블의 pk에 해당하는 a값이 존재하지 않아 사용이 불가능했습니다.
  • 또한 A테이블의 c값에는 인덱스가 걸려있지 않았고 걸 수 없는 상황이였습니다.

2. B테이블의 인덱스를 만들고 활용하기

CREATE TABLE B (
    c varchar(20),
    d varchar(20)
);
CREATE INDEX idx_b_c ON B(c);
  • B테이블의 c값에 인덱스가 설정되어 있었다면 170_000 * log2(13_000)으로 탐색을 줄일 수 있습니다.
  • 하지만 처음 테이블 생성을 신청할 때 index를 설정하지 않았고, 저는 인덱스를 설정할 권한이 없었습니다.
    DBA분들이 모두 퇴근한 시간이라(운영시간을 피해 작업을 진행하고 있었습니다) 테이블 설정을 변경할 방법이 없었고, 해당 작업은 내일 아침까지 반드시 적용되어 있어야 했습니다.

3. 해결 방법

테이블을 직접 온전하게 제어할 수 있었다면 위 두 가지 방법을 적절히 사용할 수 있었겠지만 그러지 못한 상황에서 다음과 같은 방법으로 문제를 해결했습니다.

두 테이블을 조인한 SELECT문을 실행하고 해당 데이터를 csv로 추출합니다.

SELECT 
	A.a, B.d 
FROM 
	A JOIN B ON A.c = B.c;

B테이블의 데이터를 모두 삭제하고 위에서 추출한 csv데이터를 B테이블에 import합니다.

  • 이제 B테이블은 [A테이블의 a값, B테이블의 d값]을 가지기 때문에 A테이블의 pk인 a값으로 join을 진행할 수 있습니다.

A테이블의 pk를 활용해 update를 진행합니다.

UPDATE A
JOIN B ON A.a = B.a
SET A.b = CONCAT("PREFIX",B.d);

마치며

다음날 사수님에게 이런 일이 있었다고 말씀드렸고 같이 커피를 마시며 간단히 얘기를 나눴습니다.

정말 감사하게도 고생했고 본인이 꼼꼼히 챙기지 못해서 미안하다고 말씀해 주셨습니다.

또한 문제가 발생했을 때 당연히 당황스럽겠지만 그럼에도 침착하게 대처하는게 좋을거 같다고 조언해 주셨습니다. 실제로 문제 해결 당시 저는 뭘 어떻게 해야 할지 몰라 당황하고 있었고, TPM님과 팀장님께서 도와주셔서 문제를 해결할 수 있었습니다.

이번 일을 경험삼아 부족한 부분을 보완하고 앞으로 더 잘해야 겠다는 생각이 들었습니다.

profile
기록하고 정리하는 걸 좋아하는 백엔드 개발자입니다.

0개의 댓글