이춘식 컬럼

이춘식pe

성능 데이터모델링-일련번호(Sequence)를 이용한 PK 설계고려로 프로젝트 위험을 제거하자!

작성자 : 이춘식pe 작성일 : 2016.11.10 04:11:50 댓글수 : 0 조회수 : 907

성능 데이터모델링-일련번호(Sequence)를 이용한 PK 설계고려로 프로젝트 위험을 제거하자!


 

오랫동안 바쁘다는 핑계로 컬럼 기고를 못하여 독자들에게 상당히 죄송한 마음이 됩니다. 매번 읽는 사람에게 반드시 도움이 되는 가치 있는 글을 써야 한다는 부담이 있어, 한동안 붓뚜껑을 닫아 놓고 지냈었던 것 같습니다. 다시 1월 말 2013년 첫 번째 기고를 계기로 정말 필요하고 의미 있는 기술중심의 글로 이곳을 채울 계획입니다. 

이번 컬럼에서는 특별히 어느 프로젝트에서나 사용하고 있는 Primary Key의 일련번호에 대해서 이야기를 할까 합니다. 

IT프로젝트 이슈 중 가장 큰 위험요소 중 하나가 바로 성능에 대한 이슈입니다. 성능이슈는 보통 프로젝트 말미 나 오픈 이후 상당기간 집중적으로 발생이 되고 많은 비용을 소모한 이후에 안정화 추세에 있다가 다시 데이터가 입력되었을 때 성능 이슈가 부각이 되는 사이클을 일반적으로 많이 보이고 있습니다. 

많은 사이트를 관리하다 보면 발생하는 문제가 또 발생하는 경우를 많이 봅니다. 최근에 데이터량이 커지고 처리되는 데이터의 빈도수가 많아짐에 따라 등장하고 있는 핫블럭(Hot Block)으로 인한 성능저하가 많이 발생되고 있습니다. 핫블럭이 발생하는 경우는 어느 업무든 가장 심각한 장애 상황에 해당이 됩니다. 트랜잭션이 집중된다는 것은 그 만큼 업무량이 많다는 것인데 그 때 장애가 발생하기 때문에 업무상 임팩트는 상당히 크다고 할 수 있는 것이지요. 또한 발생한 그 순간에는 임시로 처방할 수 있는 카드가 그렇게 많지 않습니다. 데이터베이스를 재기동 하여도 역시 동일한 양의 트랜잭션이 집중되어버리면 다시 장애가 발생이 되기 때문에 할 수 있는 차선책이 들어오는 트랜잭션을 앞에서 짤라 버려 일부서비스를 제한하는 극단적인 방법이 궁여지책으로 쓸 수 있는 방법이 됩니다. 

그 만큼 이 문제는 심각함을 초래한다는 것이지요… 최근에 데이터의 처리빈도수가 많아 지고 있고, 일련번호를 많이 쓰고 있기 때문에 경험하신 분들도 꽤 되시리라 생각을 합니다. 

아뭏튼 이 문제를 발생시키는 핵심요인으로서 일련번호가 그 원인을 제공하고 있는데요 발생하는 문제에 대한 이유와 함께 해결방안에 대해서 글을 정리하고자 합니다. 

PK에 일련번호를 무작정 사용할 경우,
사용자 트랜잭션이 빈도가 높거나 아니면 단위 트랜잭션당 처리하는 Step의 SQL문 발행이 빈번한 경우, 동시 집중적인 테이블 접근으로 심각한 성능저하를 보이는 경우가 많이 있습니다. 

일련번호를 사용한다는 것은 다음 모델과 같이 엔터티의 PK로서 일련번호를 사용하는 경우에 해당하고 이것은 곧 인덱스로 그대로 생성되게 됩니다. 

 

 

이렇게 되면 하나의 테이블과 4개의 인덱스가 생성되었습니다. 

대량으로 트랜잭션의 입력이 발생하는 업무 흐름을 가정하겠습니다. 

대다수 DBMS는 테이블의 데이터는 그냥 디스크 블록에 Bulk 즉, 순서유지 등을 하지 않고 비어있는 공간을 찾아 들어가기 때문에 성능에 큰 지장이 없이 처리 될 수 있습니다. 그러나, 인덱스의 경우에는 항상 순서를 유지하는 구조이기 때문에 자기 자리를 찾아서 들어가야 하고 그렇게 되면 가장 마지막에 발생한 값의 그 다음 자리에 찾아 들어가기 때문에 들어오는 모든 트랜잭션의 동일한 블록 또는 인접블럭에서 입력 작업을 처리하게 됩니다. 

인덱스가 많으면 많을수록 처리 성능저하는 가속될 수 밖에 없게 됩니다. 

대량 데이터의 입력처리가 동일 블록에서 처리된다는 것은 곧 블록의 동시성 문제가 발생하게 됩니다. 이것을 DB에서는 핫블럭(Hot Block)이라고 하는데요, 

일반적으로 업무가 가동중인 운영환경에서 이것을 해결하는 방법으로,

- 인덱스를 해시 파티셔닝으로 재 저장하는 방법
- 한 블록에 들어갈 데이터를 줄이기(오라클은 pctused 값 줄이기)
- 블록의 동시성 파라미터(오라클의 경우 INITRANS 를 늘려서)를 늘려서 처리

하는 방법이 있습니다. 

그러나 이 세 개의 방법은 소 잃고 외양간 고치기 식 방법이 될 수 밖에 없습니다. 
인덱스를 해시 파티셔닝 하게 되면 입력되는 트랜잭션은 분산되어 성능은 향상되나, 한 블록에 들어가는 데이터 양을 줄이게 되면 여러 블록에 데이터가 산재되어 있는 경우가 높아 범위처리(Range Scan)의 경우 조회 성능저하는 당연히 발생될 수 밖에 없습니다. 

블록의 동시 처리되는 양을 늘리는 경우에는 역시 인덱스를 생성하는 DBMS 내부 Cost가 집중적으로 발생되기 때문에 결과적으로 트랜잭션이 직렬성(Serializable)을 유지 할 수 밖에 없고 그것은 또한 입력 성능저하에 해당할 수 밖에 없습니다. 

즉, 근본적으로 입력과 조회 성능을 향상 시킬 수 있는 방법이 되지 않는 것을 의미합니다. 그렇다면 어떻게 해야 집중되는 트랜잭션에 대해 성능을 향상 시키는 방법이 될 수 있을까요? 

해답은 설계단계에서 데이터모델링을 할 때부터 PK체계를 고려하는 것입니다. 

 

 

이렇게 하면 입력과 조회시 성능을 향상시킬 수 있는 방법이 될 수 있습니다. 

이때 구분자로 줄 수 있는 항목으로는 가능하면 SQL의 Where절에 항상 조건으로 들어오는 값을 기준으로 하는 것이 좋습니다. 비교적 많은 업무에서는 사업소코드, 지사코드, 지역코드 등은 조회의 조건으로 들어오는 경우가 많이 있어 적절한 컬럼을 선택할 수 있을 것입니다. 

 

 

이렇게 PK를 설계를 하면 대량 데이터가 들어왔을 때 PK인덱스나 관련된 인덱스가 시도코드에 따라 일련번호 정렬구조로 저장되기 때문에 특정 블럭에 한정되어 최근에 발생된 데이터가 입력되지 않고 시도코드별로 데이터가 쌓이게 되어 여러 블록으로 인덱스가 나누어 들어가게 됩니다. 즉, 인덱스에 집중 되는 Hot Block을 피할 수 있게 됩니다. 

또한 데이터를 조회할 때 시도구분에 따라 데이터를 범위조회하기 때문에 Range Scan에 큰 문제가 발생하지 않게 됩니다. 물론, 시도코드가 SQL Where절에 포함되지 않더라도 요즘 DBMS는 인덱스 Skip Scan하는 알고리즘을 내부적으로 포함하고 있어 비교적 빠른 속도로 데이터를 식별할 수 있습니다. 

정리하면…..
설계단계에서 성능을 고려하여 데이터모델링을 할 경우 훨씬 안정적이고 우수한 데이터베이스 구조를 만들 수 있는데요, 아직은 많은 곳에서 이와 같은 원리등을 제대로 알지 못해 단순하게 일련번호만을 가지고 설계하여 구축하는 경우가 많이 있습니다. 

‘빅데이터‘라는 키워드가 나오는 정도까지 데이터 처리량이 급속하게 증가되고 있는데요… 설계단계에서부터 성능데이터모델링을 적용하여 근본적으로 성능이 향상되는 구조를 가져가도록 할 필요가 있습니다. 

성능 데이터모델링은 이 외에도 다양한 요소가 있을 수 있습니다. 제가 집필한 아는만큼 보이는 데이터베이스에서도 여러 사례를 기반으로 소개를 한적이 있는데요,, 앞으로도 계속 이 분야는 집중적으로 연구와 정리가 되어서 우리나라 데이터베이스 설계의 수준을 향상 시킬 필요가 있다고 생각합니다. 

성능 데이터모델링에 대한 주제에 대해서는 계속 실질적인 사례를 기반으로 내용을 정리하여 기고해 나갈 예정입니다. 

독자 여러분도 ‘성능 데이터모델링’에 대해 글을 보시고 좋은 아이디어 생각을 같이 공유하고 토론하는 장이 되었으면 합니다.

첨부파일

  • 댓글을 입력 하시려면 로그인 해주세요.