1. 서론
회사에서 기능 개발을 하기로 했었던 부분들이 어느정도 다 마무리 되어서 사수분과 함께 예전부터 하기로 했었던 코드 리팩토링과 쿼리 튜닝을 시작하기로 했다.
그 중에 그나마 빨리 끝낼 수 있는 쿼리 튜닝부터 하게 되었다.
2. 과정
먼저 어느 API의 어느 쿼리가 오래 걸리는지 알아내기 위해 회사에서 사용하고 있는 Datadog
을 살펴보았다.
튜닝의 기준은 소요시간이 2초 이상인 쿼리였으며 그 기준을 초과한 쿼리들 중에 3개를 담당해서 작업을 시작했다.
Datadog에 나오는 쿼리를 DBeaver로 복사해놓고, EXPLAIN
을 통해 실행 계획을 살펴보았다.
쿼리가 오래 걸리는 것들의 원인은 대부분 인덱스가 제대로 적용되지 않아서 생겼던 것이었다.
사용할 수 있는 인덱스 목록을 표시하는 Possible Keys
와 그 중에 어떤 인덱스를 사용했는지를 나타내는 keys
, 마지막으로 얼마나 많은 행을 읽어야 할 지에 대한 예측값을 나타내는 rows
를 중점으로 튜닝을 하였다.
인덱스를 사용하지 않고 있었던 곳에는 인덱스를 추가
해주었고, 인덱스를 사용하고 있지만 인덱스가 걸려있는 컬럼의 카디널리티
가 낮아서 성능이 원하는만큼 안나오는 쿼리는 카디널리티가 높은 다른 컬럼과 묶어 멀티 컬럼 인덱스
를 사용했다.
실제로 인덱스를 수정한 뒤에 실행계획이 수정하기 전과 차이가 있는 것을 볼 수 있다.
아래의 사진은 운영 DB가 아닌 개발 DB에서 실행 계획을 출력한 것이라 rows가 적지만 그래도 rows 차이가 확연히 난다.
3. 결과
쿼리 튜닝을 마친 코드를 2022-11-24 4:00pm
에 배포를 하고 하루 뒤인 2022-11-25 4:00pm
에 배포 전과 후를 기준으로 조회하여 비교해보았다.
보안을 위해 service 이름과 api 엔드포인트의 일부분을 모자이크 처리하였다.
쿼리 튜닝 전에는 2초 이상 걸렸던 쿼리 로그들이 배포 후에는 깔끔하게 사라진 것을 볼 수 있다.
2022-11-23 4:00pm
~ 2022-11-24 4:00pm
, 배포전2022-11-23 4:00pm
~ 2022-11-25 4:00pm
, 배포후