슬로우 쿼리 0건 달성기 - MySQL 쿼리 최적화 실전
“슬로우 쿼리 로그 좀 켜볼까요?” 학원 ERP 서비스에서 간헐적으로 API 응답이 느려지는 문제가 있었다. 슬로우 쿼리 로그를 켜보니 원인이 보였다. 하루 평균 15~20건. 인덱스 문제가 아니라 쿼리 구조 자체가 문제였다. 막상 보니 고칠 수 있겠다 싶었다.
“슬로우 쿼리 로그 좀 켜볼까요?” 학원 ERP 서비스에서 간헐적으로 API 응답이 느려지는 문제가 있었다. 슬로우 쿼리 로그를 켜보니 원인이 보였다. 하루 평균 15~20건. 인덱스 문제가 아니라 쿼리 구조 자체가 문제였다. 막상 보니 고칠 수 있겠다 싶었다.
크론 서버가 죽었는데 아무도 몰랐다. 청구서 발행이 안 돼서 학부모 문의가 폭주하고 나서야 알게 됐다. 그때 제일 당황한 건 “왜 몰랐지?”가 아니라 “이게 언제부터였지?”였다.
“이 코드 누가 짰어요?” 입사 첫 날 코드베이스를 열었을 때 나온 말이다. 컨트롤러 하나에 SQL, 비즈니스 로직, SMS 발송까지 다 들어있었다. 욕이 먼저 나왔고, 그 다음에 어디서부터 건드려야 하나 막막했다.
여러 서비스가 각자 로그인 시스템을 갖고 있으면 사용자는 서비스를 이동할 때마다 다시 로그인해야 한다. 사용자 불만 접수가 계속 들어오는 걸 알면서도 한동안 미뤘다. 세 팀이 동시에 움직여야 하는 작업이라서 조율이 부담이었다. 결국 점검 시간 1시간으로 끝냈다.
실시간 배차 서비스에서 20~30명의 기사가 동시에 수주 버튼을 누르면 어떤 일이 발생할까? 답은 “두 명이 동시에 수락 완료된다”였다. 로그를 처음 봤을 때 이게 실제로 일어나고 있다는 게 믿기지 않았다.
배차 서비스에서 새 배차가 등록되면 모든 기사에게 알림을 보내고 있었다. 서울 기사에게 부산 배차 알림이 가는 게 말이 안 됐다. 기사들 불만이 쌓이다가 배차 수락률이 40%까지 떨어지고 나서야 손댔다.
기사님들이 “새 수주가 늦게 뜬다”고 했다. 로그를 보니 늦게 뜨는 게 아니라, 앱이 늦게 물어보고 있었다.
방문차량 QR 출입을 붙이고 테스트하러 지하주차장에 내려갔다. 리더기가 QR을 읽고 멈췄다. 서버 응답을 기다리다 타임아웃이 났다. 지하 2층에는 신호가 거의 없었다.
“결제 연동 문서 좀 주세요”라고 했더니 .asmx?wsdl 링크가 왔다. 2022년에 SOAP을 만질 일이 있을 거라고는 생각해본 적이 없었다.
main.py를 열었더니 include_router가 60줄 가까이 이어져 있었다. 도메인을 하나 추가하면 네 군데를 고쳐야 했고, 어느 날 하나를 빼먹어서 API가 404를 냈다.