카테고리 없음

SQL - 대량 데이터에 따른 성능, 테이블 분할

비뀨_ 2022. 12. 27. 04:05

코로나에 확진이 되어버려 며칠 골골댔습니다...

원본 링크

 

1. 대량 데이터발생에 따른 테이블 분할 개요

고속도로 차선이 20차선이라도, 교통량이 많으면 도로가 막히는 것처럼

한 테이블에 데이터가 많고, 하나의 하드웨어 공간에 저장되어 있으면 성능저하가 일어난다.

이런 경우 트랜잭션이 분산될 수 있도록 테이블 단위에서 분할을 할 필요가 있는 것이다.

 

테이블에 대한 수평 / 수직분할 절차

테이블에 대한 수평분할/ 수직분할에 대한 결정은  다음의 4가지 원칙으로 적용하면 된다.

  • 데이터 모델링을 완성
  • 데이터베이스 용량 산정
    • 용량산정 : 어느 테이블에 대용량의 데이터가 쌓이는지 분석
    • 칼럼이 많을 경우 - 트랜잭션 특성에 따라 테이블을 1:1 형태로 분리할 수 있는지 검증
    • 칼럼이 적지만 데이터용량이 많을 경우 - 테이블에 대해 파티셔닝 전략을 고려.
  • 대량 데이터가 처리되는 테이블에 대해 트랜잭션 처리 패턴을 분석
  • 칼럼 or 로우 단위로 집중화된 처리가 발생하는지 분석해 검토 

 

 

칼럼이 많아지게 되면 물리적인 디스크에 여러 블록에 데이터가 저장되게 된다.

 

따라서 데이터를 처리할 때  여러 블록에서 데이터를 I/O 하기 때문에 SQL문장의 성능이 저하될 수 특징을 가지게 된다.

물론, 테이블에 칼럼이 많아지는 현상은 정규화이론인 함수적 종속성에 근거하여 당연히 하나의 테이블에 설계할 수는 있다.

그러나 대량 데이터를 가진 테이블에서 불필요하게 많은 양의 I/O를 유발하여 성능이 저하되는 경우에는 이것을 기술적으로 분석하여 성능을 향상하는 방법으로 분할할 수 있다.

 

로우체이닝 : 두 개 이상의 블럭에 하나의 로우가 저장되어 있는 형태

로우마이그레이션 : 블럭에서 수정이 발생하면 수정된 데이터를 해당 블럭에서 저장하지 못하고 다른 블록의 빈 공간을 찾아 저장하는 방식.

 

위 두 개가 발생하면 DB의 메모리에서 불필요한 I/O가 많이 발생하여 성능이 저하된다.

 

1-1 한 테이블에 많은 수의 칼럼을 갖는 경우

하나의 로우의 길이가 8Kb이고, 하나의 블록은 2Kb이다.

하나의 로우는 4블록에 걸쳐 저장된다.

 

이때 테이블의 칼럼이 100개라고 한다면, 100개의 칼럼은 4블록에 나눠져서 저장될 것이다.

그렇다면 물리적으로 칼럼의 값이 넓게 분포되어 있어서 디스크 입출력(I/O)이 많이 일어난다.

디스크에 저장된 모습 그려보기

 

칼럼을 다 그리기는 힘들어서...원본의 이미지 가져왔습니당...

 

많은 칼럼을 가지고 있을 때는 어떤 칼럼에 대해서 트랜잭션이 집중적으로 발생하는지 분석해

테이블을 쪼개주면 디스크 I/O가 감소해 성능이 개선되게 된다.

 

1-2. 대량 데이터 저장 및 처리로 인한 성능

테이블에 많은 양의 데이터가 예상되면, 파티셔닝을 적용하거나, PK에 의해 테이블을 분할하는 방법을 적용할 수 있다.

ORACLE에서는 

  • List Partition : 특정값 지정
  • Range Partition : 범위 지정
  • Hash Partition : 해쉬 적용
  • Composite Partition : 범위 & 해쉬 복합

데이터량이 몇 천만 건이 넘어서면 서버가 좋고, 인덱스를 잘 생성해준다고 하더라고 SQL문장의 성능이 나오지 않는다.

이 때는 논리적으로는 하나의 테이블로 보이지만 물리적으로 여러 개의 테이블스페이스에 쪼개어 저장될 수 있는 구조의 파티셔닝을 적용하도록 한다.

 

가. RANGE PARTITION 적용

 

가장 많이 사용.

테이블을 날짜 or 숫자로 분리 가능하고,

영역별로 트랜잭션 분리 된다면 Range Partition사용.

PK는 요금일자 + 요금번호이다.

데이터건수가 1억건이라고 가정해보자. 하나의 테이블로는 데이터가 너무 많이 존재해서 성능이 느린 경우다.

이 때 요금의 특성상 월단위로 처리하는 경우가 많기 때문에 PK의 요금일자의 년+월로 12개의 파티션 테이블을 만들어서처리했다.

 

SQL 문장을 처리할 때에는 하나의 테이블처럼 보이는 요금 테이블을 이용하지만 내부적으로 SQL Where절에 비교된 요금일자에 의해 찾아가서 1억건의 정보를 찾는 것이 아닌, 파티션 테이블의 데이터 개수인 1000만건을 처리해 성능을 개선시킬 수 있다.

 

나. LIST PARTITION 적용

지점, 사업소, 사업장, 핵심 코드값 등으로 PK가 구성되어 있고, 데이터가 대량으로 있다면 List Partition을 사용할 수 있다.

위의 이미지는 고객 테이블의 1억개의 데이터가 있다고 가정했을 때

현재의 고객 테이블에서만 데이터를 처리하기에는 SQL 성능이 저하가 될 수 있다.

그래서 지역을 기반으로 파티션을 적용했다. 

 

장점 : 대용량 데이터를 특정값에 따라 분리할 수 있음.

단점 : Range Partition 처럼 데이터 보관주기에 따라서 쉽게 삭제하기는 어렵다.

 

다. HASH PARTITION 적용

Hash 조건에 따라 해싱 알고리즘이 적용되어 테이블에 데이터가 정확하게 어떻게 들어갔는지 모른다.

그렇기 때문에 데이터 보관주기에 따라서 삭제할 수 없다.