배경

우리 회사의 고질적인 VOC 중 하나로 채팅에서 검색 시 이전 채팅 데이터에서 내용, 파일, 이미지에 대해서 조회가 되는데 없는 단어로 검색 시(ex. 똛, 쌂, 뺡 같은 외계어, 혹은 사용하지 않은 단어) 전체에 대해 검색을 진행하여 속도가 너무 느려 타임아웃이 발생하여 속도개선 요청이 지속적으로 들어왔습니다.

진행

  • 먼저 원인이 되는 부분을 찾았을 때 like ‘%단어%‘로 검색하는 부분이 다수 존재하였고, b-tree index만 사용하고 있어서 해당 부분에서 index가 타지 않고 있었습니다. 그래서 ‘아 이건 index 안타지 다른 부분 고쳐서 성능개선 해봐야겠다.’ 하고 아래의 쿼리 실행 순서를 따라 보며 성능 개선을 진행했습니다.

쿼리의 기본적인 실행 순서는

  1. from
  2. where
  3. group by
  4. having
  5. select
  6. order by
    순이다.
  • 해당 순서대로 봤을 때, 중복되는 서브쿼리가 많았고 그 부분을 with절로 빼봤지만 문제가 되는 부분은 동일했습니다.
  • 그래서 like에 ‘%단어%‘로 조회할 경우 index가 타지 않는 것으로 알고 있지만 왜 안타는지에 대해선 알아야 설명을 하든 다른 방법을 찾을 수 있지않을까 싶어 검색을 하게 되었고,
    https://k3068.tistory.com/106 글을 읽고 Full Text Search에 대해서 알게 되었습니다.
    좀 더 찾아보니 postgres에서도 Full Text Search를 적용할 수 있다는 사실과 작동방식, 적용법을 알아낼 수 있었습니다.
  • Postgres에서 Full Text Search를 하는 방법은 크게 2가지가 있었다.
  • 첫 번째 방법은 바꿔야하는 부분도 많고, 단어가 일치해야만 가져오게 되어있어서 원하는 방법이 아니었고, 두 번째 방법의 pg_bigm 모듈 사용방식이 변경사항은 적으면서 한국어를 지원하고 속도도 훨씬 빨랐고 2글자부터 full text search가 가능하면서 용량도 적었다.(이렇게 완벽할수가 있나 싶었다!)

위의 with절과 GIN index를 적용하고 76초에서 0.073초로 99.9% 개선할 수 있었고, 동일 VOC 유입이 89% 줄어들었습니다.

결론

  • 다 안다고 생각하지 말고 불가능하다면 불가능한 이유에 대해 파고들고 다른 방법은 없는지 찾아봐야 하고, 내가 제대로 알고있는 것이 맞는지 새로 나온 것은 없는지 항상 알아보고 귀를 기울여야겠다고 생각했습니다.

참조