본문 바로가기
DataBase

DB - 성능 개선을 위한 테이블 분할

by khds 2022. 4. 26.

 

데이터베이스의 성능을 개선하기 위한 방법 중 하나가 테이블 분할이다. 

테이블 분할은 어려움이 따르는데 그 이유는  기존에 설계된 테이블 구조를 변경해야 하고 이미 개발된 프로그램을 변경해야 하기 때문이다.

보통 테이블을 변경하는 원인은 DB 설계시 정규화를 소홀했거나 용량 산정을 잘못했기 때문이다. DB는 설계가 매우 중요하기 때문에 초반에 설계를 잘못한다면 성능상의 문제가 생기기 마련이다. 그렇기에 잘못된 설계 및 정규화로 인한 성능 저하를 해결하기 위해 테이블 분할을 하는 것이다. 

 

테이블 분할은 크게 수직분할과 수평분할로 나눈다. 

수직분할은 컬럼을 기준으로 테이블을 분리하는 것을 의미하고 수평분할은 로우를 기준으로 테이블을 분리하는 것을 의미한다. 테이블의 컬럼 수가 많을수록 I/O에 대한 부하가 걸리고, 로우 수가 많을수록 인덱스에 대한 부하가 따른다. 그렇다고 모든 테이블을 분리한다고 해서 성능 향상을 이룰 수 있는 것은 아니다. 대용량이면서 성능 이슈가 있는 테이블이 주된 대상이다. 

 

아래 사진을 한번 봐보자.

출처: 개발자를 위한 인덱스 생성과 SQL 작성 노하우 - 이병국

 

 

위와 같이 수직분할은 컬럼들을 나누는 것이고 수평분할은 로우들을 나누는 것이라고 할 수 있다. 

 

 

I/O 성능 개선을 위한 수직분할

한 테이블에 컬럼이 매우 많다고 생각해보자. 하나의 로우가 매우 긴 양이될 것이다. 그렇다면 이러한 데이터를 저장할 때 디스크의 여러 블록에 데이터가 저장되므로 I/O 성능 저하를 불러올 수 있다.  

이렇게 컬럼이 많다면 '로우의 체인'과 '로우의 이주'가 많이 발생하여 성능이 저하된다.

로우의 체인은 길이가 너무 커서 하나의 블록에 저장되지 못하고 다수의 블록에 나누어져 저장하는 것이고 로우의 이주는 수정된 데이터를 해당 데이터 블록에 저장하지 못하고 다른 블록의 빈 공간에 저장하는 것이다. 

로우의 체인 및 이주에 대해서 자세한 내용은 https://khdscor.tistory.com/m/46 를 참고하길 바란다. 

 

데이터 저장구조와 특징(클러스터링 팩터)

스프링 프로젝트를 하면서 최적화에 대한 문제를 여러 번 직면했다. api 횟수를 줄이는 문제, DB와의 통신 횟수를 줄이는 방식, N +1 문제, JPA 읽기 모드, 캐시, DB 검색 성능 향상(인덱스 및 join성능

khdscor.tistory.com

 

 

로우의 체인 및 이주가 발생해 많은 블록이 사용하게 되면, 불필요한 I/O가 발생해 성능이 저하된다.

또한 데이터에 대한 범위 검색을 할 경우 더 많은 I/O가 발생되므로 성능이 저하된다. 

수많은 컬럼을 동시에 조회하는 경우는 드물다. 각각의 상황 및 조회 조건에 맞게 이용되는 컬럼들로 그룹을 묶어서 테이블 분할을 생각할 수 있다. 조회나 처리에 대한 분산을 가능하게 하는 컬럼들을 기준으로 테이블을 분리한다면 성능을 크게 개선할 수 있을 것이다. 

 

 

처리 성능 개선을 위한 수평분할

만약 한 테이블에 대량의 데이터가 존재하고 트랜잭션이 몰린다면 성능 저하가 생길 것이다. 대량의 데이터가 하나의 테이블에 있으면 인덱스 정보 생성 시 부하가 올라갈 것이다. 인덱스를 찾는 깊이가 깊어지고 인덱스가 커질수록 더 많은 성능 저하를 발생시킨다. 조회하는 성능보다는 데이터를 처리하는 성능에 더 큰 영향을 끼치게 된다. 이럴 경우에 수평분할을 이용하는 것이다.

 

 

논리적으로는 같은 테이블이지만 물리적으로 서로 다른 여러 개의 테이블 스페이스에 나눠 저장하는 것을 '파티셔닝(Partitioning)'이라고 한다. 이러한 파티션 기법을 통해 테이블을 분할할 수 있다. 

파티션 종류는 Range, Hash, List, Composite 파티션이 있다. 가장 널리 사용되는 기법은 Range 기법이며 자세한 사항은 https://gmlwjd9405.github.io/2018/09/24/db-partitioning.html 를 참고하길 바란다. 

 

[DB] DB 파티셔닝(Partitioning)이란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

아래는 수직분할과 수평분할의 간단한 예시이다. 

 

수직분할 예시

 

 

수평분할 예시

 

 

참고

https://gmlwjd9405.github.io/2018/09/24/db-partitioning.html

 

[DB] DB 파티셔닝(Partitioning)이란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

 

개발자를 위한 인덱스 생성과 SQL 작성 노하우 - 이병국