1주일 회고(2/18~2/24)

2 minute read

1주일 회고(2019-02-18~2019-02-24)

  • MSSQL 인덱싱
  • 프래그래머스 온라인 코딩 테스트 시험

MSSQL 인덱싱

경주에 또 긴급 출장을 가야했다. 이유눈 문서 목록 조회의 급격한 속도저하가 발생했기 때문이다. 지난번 출장에서 목록 조회하는 쿼리를 튜닝하여 개선(join 순서 조정)하였는데 또 그런 문제가 발생하고 있다니 기가찰 노릇이였다.

급히 출장지의 사무실 컴퓨터로 운영서버에 접속했다. Windows server 2012 R2 서버 관리자가 보고하는 내용과 에러 로그, DB 상태를 빠르게 확인했다.

확인 결과 이상이 없었다. IIS 풀도 잘 돌고 있고 DB에 문제가 생긴것도 없다. 그렇다면 실제 서비스 루틴에서 문제가 생긴다는건데 확인결과 문서 목록을 리턴하는 서비스(WCF 서비스)에서 특정 문서 목록을 조회하면 시간이 엄청나게 오래 걸린다는것이다.

해당 문서 목록을 가지고 오는 과정은 아래와 같다.

  1. 특정 문서 목록을 조회하는 서비스
  2. 문서 목록을 가지고 오는 공용 서비스
  3. DB에서 데이터 조회

이 과정을 하나 하나 분석한 결과, 지난번에 튜닝한 쿼리가 쓰이는 공용 서비스 문제가 아니라 1. 특정 문서 목록을 조회하는 서비스 가 공용 서비스의 리턴 결과에 후처리를 위한 데이터를 가지고 오기 위해 쿼리를 날리는데 이 과정에서 최소 40s 최대 1m 40s가 걸리는 것이였다. (사용자들이 얼마나 답답했을까..죄송합니다.)

일단 해당 쿼리의 동작 과정을 설명하면 아래와 같다.

  1. 특정 유형의 문서 Record중 최신 버전의 Record를 찾는다.
  2. 조건에 따라 필터한다.

아주 심플한 쿼리인데 왜 무지막지한 시간이 걸리는걸까..(실행 계획을 보았다면 바로 답이 나왔을텐데 나는 쿼리부터 부분별로 나누어 실행했다.)

우선 최신버전을 가지고 오기 위해 Partition by Id를 하여 max 버전을 뽑아내는데 여기서부터가 문제였다. 문서별로 Record가 300개가 쌓인것이였다. 이말인 즉슨 저장 이력이 300개가 생긴건데 문제가 되는 문서는 유저가 조작할수 없고 타 시스템에서 이관하는 문서라 저장 이력이 저렇게 생기는것 자체가 이상한것이였다.

원인은 찾았다. 그럼 이걸 어찌 해결한다.. 잠시 고민을 하니 아래의 방법이 떠올랐다.

  1. 최신 버전을 제외한 저장 이력 정보를 삭제한다.
  2. 최신 버전을 가지고 있는 View를 활용한다.

1번 방법은 위험 부담이 있다. 잘못 이력을 삭제했다간 연계된 기능에 영향을 미칠수 있다고 판단된다. 그럼 2번 방법이지.

View를 활용하니 확실히 속도가 개선되었다. View를 사용했는데 왜 빨라지는가? 참고링크 View는 결과를 캐싱하기 때문에 해당 쿼리를 캐싱되지 않은 상태에서는 조금 느릴지라도 캐싱된 이후에는 굉장히 빠른 응답을 보여주게 된다.

기존 응답 시간 : MIN 40s / MAX 1m 40s View 적용한 응답 시간 : MIN 3s / MAX 5s

응답 시간만 본다면 매우 큰 차이다. 이대로 적용하기 전에 실행계획에 어떤 차이가 있는가 하여 실행계획 표시 옵션을 적용하고 쿼리를 실행했더니..


--쿼리 프로세서에서는 다음 인덱스를 구현하는 경우 쿼리 비용이 98.254%만큼 향상될 수 있다고 평가합니다.

/*
USE [DB_NAME]
GO
CREATE NONCLUSTED INDEX [인덱스명]
ON [dbo].[테이블명](컬럼명)
INCLUDE(ID, VERSION, Valid, Status, DocNumber, Type, xxx, xxx)
GO
/*

아니 이게 뭔가? 이게 무슨 메시지야? MSSQL 쓰면서 난생처음 보는 메시지가 나오는게 아닌가. 잽싸게 검색해보니 해당 쿼리가 현재 적용되있는 인덱스를 사용하지 않고, 실행시간이 오래걸리는 쿼리에 대해 쿼리 프로세서가 분석하여 개선방안을 제안하는것이였다.

아니 그러니까 지금 쿼리가 DBMS 입장에서 도저히 눈뜨고 못볼 정도라는거 아닌가..

팀장님과 잠시 상의 끝에 인덱스를 적용하기로 했다. 인덱싱 적용으로 인한 삽입, 삭제, 수정의 성능 손실보다 응답 시간 개선의 이득이 매우 크므로 그렇게 결정한것이리라.

무튼 인덱스 적용이 끝나고 기존 쿼리를 실행했더니 응답시간이 1ms 수준으로 복구 되었다.

이번에 배운점은

  1. 인덱싱으로 응답시간 개선할 수 있다는것.
  2. 너무 느린 쿼리는 DBMS가 인덱스를 제안한다는것.
  3. DB 정말 어렵다.

DB 잘하시는분 존경합니다.

이걸로 마무리 되었는줄 알았는데 LIKE 검색이 적용되는 문자열 검색시 속도 저하 문제가 또 발생해서 다음주에 잡을 예정.. 흑흑

프래그래머스 온라인 코딩 테스트 시험

2월 23일 온라인 채용박람회를 진행하는 프로그래머스 온라인 코딩 테스트 시험을 쳤다가 망했다.(이 글을 쓰기 몇시간 전에 탈락 메일이 왔다.)

뭔 시작부터 망했냐고 하냐면.. 3문제중에 반도 제대로 못풀었으니 망했지.

지금 이 글을 쓰고있는 와중에도 헛웃음과 자괴감이 든다. 알고리즘 스터디는 왜 한걸까. 그래도 과거에는 문제 자체를 이해하지 못했지만 지금은 어떻게 접근하면 되는지는 알게되었으니..

열심히 해야겠다. 나는 아직 한참 멀었다. 코딩을 사랑해야지.

Updated:

Leave a comment