포스트

도구를 고르는 법 — 두 번 실패하며 배운 것

데이터에 맞는 타입을 고르면 충분할까? 위경도로 거리를 직접 계산한 실패로 '먼저 찾아보는 습관'을 얻었지만, 다음 프로젝트에서 그래프 DB를 고르며 그것만으로는 부족하다는 걸 알았다.

도구를 고르는 법 — 두 번 실패하며 배운 것

도구는 데이터의 타입만이 아니라, 그 데이터를 어떻게 쓰는지까지 봐야 고를 수 있다. 두 번 실패하고 배운 것이다.

🌏 지구를 구라고 놓고, 거리를 직접 계산했다

플로깅 커뮤니티 프로젝트를 할 때였다. 두 지점 사이의 거리를 구해야 했는데, 나는 아주 자연스럽게 공식을 검색했다. 지구를 구로 놓고, 두 좌표를 구면 코사인 공식에 넣어 거리를 직접 계산하는 코드를 짰다.

돌이켜보면 이상한 건 계산이 아니라 내 사고의 출발점이었다. 나는 “이 거리를 어떻게 직접 구하지?”에서 시작했다. “이런 걸 대신 해주는 도구가 이미 있지 않을까?”라는 질문 자체를 안 했다. 한참 뒤에야 알았다. 데이터베이스에는 위치 데이터를 위한 전용 공간(spatial) 타입과 함수가 이미 다 들어 있었다. 내가 손으로 짠 그 계산을, 훨씬 정확하게 대신 해주는 게 처음부터 있었던 거다.

그때 하나를 배웠다.

데이터를 기본형에 우겨넣고 로직부터 짜기 전에, 그 데이터에 맞는 타입이 이미 있는지부터 찾아보자.

🕸️ 그 습관을 써먹었는데, 또 미끄러졌다

두 번째 실패가 재밌는 건, 하필 그 습관을 잘 지켜서 나왔다는 점이다.

다음 프로젝트는 수학 취약점을 진단해 맞춤 학습 경로를 제시하는 서비스였다. 여기선 “이 개념을 알려면 저 개념을 먼저 알아야 한다”는 선수학습 관계를 다뤄야 했다. 예전의 나였으면 그냥 관계형 DB에 테이블 몇 개 만들고 조인으로 씨름했을 거다. 그런데 이번엔 습관대로 먼저 찾아봤다. 그리고 알게 됐다. 관계형 DB 말고 그래프 데이터베이스라는 게 따로 있고, 노드와 엣지로 관계를 그대로 표현한다는 걸. “이거다” 싶어서 Neo4j로 구현했다.

타입은 제대로 찾은 거였다. 데이터가 그래프 모양이니 그래프 DB. 여기까진 맞았다.

그런데 막상 붙여놓고 실제로 어떤 조회가 나가는지 들여다보니, 뭔가 이상했다. 내가 정작 하는 질의는 대부분 특정 개념의 선수 경로를 한 방향으로 거슬러 올라가는 단방향 순회였다. 그래프 DB가 진짜 빛나는 양방향 탐색이나 복잡한 관계 질의는 이 서비스에서 거의 나오지 않았다. 게다가 규모를 세어보니 노드 1,600여 개, 엣지 3,400여 개. 그렇게 큰 그래프도 아니었다.

이 정도 단방향 순회라면, 관계형 DB의 재귀 CTE(WITH RECURSIVE)로도 충분히 되는 일이었다.

여기서 내가 첫 번째와 똑같은 실수를 한 겹 위에서 반복했다는 걸 깨달았다. 첫 번째 땐 데이터에 맞는 타입이 있는지를 안 봤다. 이번엔 타입은 봤는데, 그 데이터를 실제로 어떻게 쓰는지(접근 패턴)와 규모를 안 봤다. 데이터의 ‘모양’만 보고 도구를 고른 거다.

📉 감이 아니라 숫자로 다시 평가했다

그래서 선택을 다시 따져봤다. RDB가 나을 것 같다는 짐작만으로 바꾸고 싶지는 않았다.

같은 선수 경로 조회를 MySQL 재귀 CTE로 다시 구현했다. 곧바로 갈아타는 건 위험하니 피처 플래그로 두 구현을 나란히 돌리다가, 확인이 되고 나서 전환했다. 측정은 워밍업 3회 뒤 100회를 쟀고, 회귀 테스트로 성능을 고정해뒀다. 나중에 코드가 바뀌어도 느려지면 바로 걸리도록.

숫자는 이렇게 나왔다.

지표전환 후메모
응답 시간 (깊이 3 조회)14.0 → 2.2ms (84%↓)전환만으로
운영 DB 종류2종 → 1종Neo4j + MySQL 병행을 MySQL 하나로
컨테이너 메모리≈1,007 → 701MiB (30%↓)그래프 탐색까지 MySQL로 흡수

가장 의외였던 건 속도가 빨라진 이유였다. 보통 더 좋은 걸 얹으면 빨라진다고 생각하는데, 여기선 반대였다. 화려한 전용 도구(Neo4j)를 걷어냈더니 시스템이 단순해졌고, 그러면서 오히려 빨라졌다. DB가 하나로 줄었으니 백업도, 모니터링도, 장애 때 들여다볼 곳도 하나로 줄었다. 없앤 게 성능이 아니라 복잡도였던 셈이다.

이건 예전에 쿠폰 락 실험에서 분산 락까지 만들어보고 결국 가장 단순한 DB 행 락으로 한 칸 내려왔던 것과 완전히 같은 결이다. 끝까지 가보고, 근거를 손에 쥔 채로 한 칸 내려오는 것. 그때도 그랬지만, 안 써보고 “그래프니까 그래프 DB겠지” 하고 믿었다면 지금도 필요 없는 저장소 하나를 더 이고 있었을 거다.

💡 배운 점 — “이게 있나”에서 “이게 나한테 맞나”로

두 번의 실패를 겹쳐놓으니 배움이 한 층씩 올라가 있었다.

  • 첫 번째: 직접 짜기 전에, 데이터에 맞는 타입이 있는지 찾아보자.
  • 두 번째: 타입(데이터의 모양)만 보면 절반이다. 그 데이터를 실제로 어떻게 쓰는지, 얼마나 큰지까지 봐야 도구가 맞는지 알 수 있다.

그래프 모양이라고 무조건 그래프 DB가 답은 아니었다. 단방향 조회에 규모도 작다면 재귀 CTE가 더 단순하고 운영 비용도 낮았다. 도구의 강점은 카탈로그에 적힌 스펙이 아니라, 내 워크로드 위에서 결정된다는 걸 두 번 데고 나서야 알았다.

그래서 지금은 기술을 고를 때 “이게 있나”에서 멈추지 않는다. 거기서 한 걸음 더 가서 이렇게 묻는다.

내 접근 패턴과 규모에 이게 맞나? 그리고 이 선택이 나중에 남길 운영 부채는 무엇인가?

도구를 얹는 결정에는 항상 청구서가 따라온다. 그 청구서까지 미리 읽어보고 결정하는 것 — 두 번의 실패가 나한테 가르쳐준 건 결국 이거였다.


이 글은 직접 진행한 두 프로젝트의 기술 선택 경험과 측정 기록을 바탕으로, AI(Claude)의 도움을 받아 작성했습니다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.