1년 차의 열정, 그리고 기술 부채
2024년 투입되었던 프로젝트는 지금 생각해도 아찔하다. 1~3년 차 주니어 개발자들이 모여 아둥바둥 진행했던 프로젝트. "21일 연속 밤 11시 퇴근"이라는 기록을 세울 만큼 치열했고, 그만큼 전우애도 깊었다.
당시 솔루션 요구사항이 기존과 달라 목록과 상세를 복잡하게 보여줘야 했다. 온갖 분류 코드가 들어가다 보니 GROUP BY를 남발할 수밖에 없었고, 무려 9~10개의 테이블을 조인해야 하는 괴물 같은 쿼리가 탄생했다.
당시 나는 SQLD 자격증 공부를 하며 알게 된 '집계 함수', '윈도우 함수'를 실무에 적용해 본다는 것만 집중하고 "결과만 나오면 된다"는 생각으로 성능은 전혀 고려하지 않았고, 그 업보는 1년 뒤에 돌아왔다.
문제는 2025년에 터졌다
2025년 2월, 기존 월별로 약 10만건씩만 조회한다는 데이터는 월 100만건이 넘어가면서 쿼리는 비명을 질렀다.
- 데이터: 약 100만 건 (월 별 조회시 데이터)
- 조인 테이블: 9~10개
- 조회 시간: 60초 이상 (Time-out 발생 직전)
사용자가 페이지 하나를 보는데 1분을 기다려야 하는 상황. 더 이상 방치할 수 없었다.
무엇이 문제였나? (Self Code Review)
내부망이라 당시 쿼리를 가져올 순 없지만, 복기해보면 내 쿼리는 총체적 난국이었다.
- 선(先) Select, 후(後) Where: 필요한 데이터를 먼저 추리는 게 아니라, 일단 서브쿼리로 전체 데이터를 다 퍼올린(SELECT *) 다음, 가장 바깥쪽에서 조건을 걸고 있었다. DB가 100만 개를 다 읽고 나서야 필터링을 하니 느릴 수밖에.
- 무용지물 인덱스: 인덱스를 걸긴 했지만, 실행 계획(Execution Plan)을 보니 내가 만든 인덱스는 타지도 않고 Full Table Scan을 하고 있었다.
- 습관성 SELECT *: 프로젝트 초반, 요건이 계속 바뀌니 "일단 다 조회해놓고 나중에 골라 쓰자" 했던 코드가 그대로 남아 있었다. 불필요한 데이터까지 조인하느라 I/O 낭비가 심했다.
해결: 60초를 1초로 만든 튜닝 과정
성능 개선을 위해 실행 계획을 뜯어보며 하나씩 고쳤다.
- 드라이빙 테이블(Driving Table) 재선정: 무작정 조인하지 않고, 중심이 되는 Master 입수 테이블을 기준으로 잡았다. 기준 데이터를 먼저 읽고, 거기에 다른 테이블을 붙이는 방식으로 변경했다.
- 인덱스 최적화: WHERE 절에 들어가는 조건을 분석해 단일 인덱스 대신 복합 인덱스를 태웠다.
- MAX/TOP 로직 개선 (Tibero): 최신 데이터 하나를 가져오기 위해 서브쿼리로 GROUP BY 하던 로직을 Tibero의 WITH 절이나 힌트, 윈도우 함수를 활용해 스캔 범위를 최소화했다.
- 조건절 및 SELECT 다이어트:
- 화면에 필요한 컬럼만 명시해서 가져오도록 수정했다.
- 특히 조건절 최적화가 중요했다. 당시엔 불안한 마음에 IS NOT NULL 체크면 될 것을 불필요한 IF문과 EXISTS를 덕지덕지 붙여놨었는데, 이를 단순하고 명확한 조건으로 모두 걷어냈다.
글로 적으니 간단해 보이지만, 실제로는 혼자 해결하기 버거워 사내 선임님들은 물론 국비 교육 들을 때 멘토님까지, 총 6~7명을 붙잡고 조언을 구하며 매달렸던 처절한 시간이었다.
대량 데이터(100만 건) 환경에서 테스트한 결과는 드라마틱했다.
- 집계 목록 조회: 30초 ▶ 3초
- 상세 페이지 조회: 60초 ▶ 1초 미만
이번 경험을 통해 개발자로서 한 단계 성장했다. 단순히 기능 구현에 그치지 않고 인덱스의 중요성, 필요한 데이터만 SELECT 하는 습관 등 '성능'을 고려하는 시야를 갖게 되었다. 무엇보다 실행 계획이 모든 정답을 알려주진 않더라도, 내 쿼리의 병목 지점을 파악하는 나침반이 되어준다는 것을 확실히 배웠다.
튜닝을 마치고 문득 이런 생각이 들었다. "애초에 테이블을 하나로 합쳐서 설계했다면, JOIN 지옥 없이 편하지 않았을까?"
그래서 실제로 바로 다음 프로젝트에서는 조회 성능과 개발 편의성을 위해 과감하게 테이블을 합치는 반정규화(Denormalization) 전략을 시도해 봤다.
솔직한 후기는? "쿼리 짜기가 너무 편하다." 아직 프로젝트 초기라 데이터가 많지 않아서일 수도 있지만, JOIN 신경 안 쓰고 SELECT만 하면 되니 개발 속도가 확연히 빨랐다. 물론 책에서 배운 대로 데이터가 쌓이면 정합성 문제나 관리 포인트가 늘어날 수도 있겠지만...
그건 그때 가서 또 깨지고 부딪히며 배워보려 한다. 개발에 정답은 없으니, 상황에 맞춰 최선을 선택하고 결과를 감당하는 과정 자체가 성장이 아닐까..
'Projects > Work Experience' 카테고리의 다른 글
| 폐쇄망/내부망 환경에서 Maven 빌드 실패 해결 가이드 (IntelliJ + .m2 설정) (1) | 2026.01.19 |
|---|