jongviet

Feb 28, 2024 - 3일만에 900만건의 데이터 생성.. RDB 파티셔닝 / 인덱싱 적용 본문

카테고리 없음

Feb 28, 2024 - 3일만에 900만건의 데이터 생성.. RDB 파티셔닝 / 인덱싱 적용

jongviet 2024. 2. 28. 18:57

*2월28일

 

너무 오랜만에 포스팅을 한다. 게을러진 탓도 있고 실무에서 벌어지는 일들을 대응하느라 마음의 여유가 부족했다. 

 

회사 비즈니스 모델이 전환되면서 엄청난 규모의 데이터가 매일 생성되게 되었다. (일 기준 약 300만..) 제휴를 맺고 있는 각 파트너에게 다양한 방향에서 여러 지표를 제공해야해서 다양한 이벤트(유저 동작)으로 인해 파생되는 로우데이터가 매우 잘게 나뉘어 생성되고, 그에 따라 매일 생성되는 데이터의 수도 압도적으로 많아졌다.

 

그전까지 NoSQL을 사내에서 주력으로 사용하다보니 여러 개념이 부족했었는데 이번 기회에 RDB에 데이터를 축적하면서 RDB에 대해 많이 익히게 되었다.

 

먼저 RDB 파티셔닝에 대한 개념이 없어서 엄청나게 많은 수가 생성되는 데이터 타입을 별도 테이블로 이관 하는 작업을 하고 있었다... 마이그레이션 작업을 함과 동시에 진짜 이게 맞나 싶어 서칭을 했고, 파티셔닝을 통해서 동일한 테이블 내에서 여러 테이블로 논리적으로 분리 할 수 있다는 개념을 알게 되었다.

 

파티셔닝에는 아래와 같은 개념이 있고,

  • 수직적 파티셔닝:  칼럼 단위 째는 것. 즉 칼럼 단위 테이블 분할임
  • 수평적 파티셔닝: 테이블의 row를 분할하여 여러개로 나누는 것. 범위 분할(날짜), 목록 분할(특정 타입 칼럼 기준) 등이 있다.

결과적으로 날짜 범위 파티셔닝을 적용한 후 아래와 같이 월 별 파티셔닝을 별도 생성하였다.

 

기본적인 커맨드는 서칭해보면 쉽게 나오지만 아래와 같다. 해당 날짜 범위에 속하지 않는 데이터가 삽입될 시 에러가 뜬다. 자동으로 굴러가도록 설정할 방법이 있긴 한 것 같은데 현재 급한 상황이라 수동으로 현재~25년까지 월 별로 파티셔닝을 별도 생성했다.

 

create table {partition_table_name} partition of {source_table}
for values from ('2025-04-30T15:00:00.000Z') to ('2025-05-31T14:59:59.999Z');

 

기존 테이블 -> 파티셔닝된 테이블로 마이그레이션 시 아래와 같이 실행시간을 먼저 확인해보고 진행하는게 낫다. 아래는 두 테이블 칼럼이 모두 같다는 가정하에 진행하는 것이고, 칼럼이 다르거나 특정 칼럼의 값이 변경되어야 한다면 별도 수정이 필요하다.

 

BEGIN; // 실 테이블에 적용 없이 테스팅만 할 때 사용
EXPLAIN ANALYZE // 본 쿼리 분석하여 결과 값 리턴
INSERT INTO new_table
SELECT * FROM original_table;
ROLLBACK; // 실 테이블에 적용 없이 테스팅만 할 때 사용

 

다시 하나의 테이블이 900만 건의 데이터를 몰아 넣다보니 당연히 인덱싱이 필요하게 되었다.

인덱싱의 경우, 카디널리티, 선택도, 활용도, 전체 테이블 로우의 수를 감안하여 설정하였다. 서칭해보면 다 독립적으로 카디널리티가 높을 수록 좋다 / 선택도가 낮을 수록 좋다... 와 함께 원론적인 소리만해서 “그래서 어떤 칼럼에 적용을 하란거냐...”가 입밖으로 뛰쳐 나왔다. 
결론적으로 전체 테이블 로우의 수와 활용도가 매우 중요하다. 현재까지 약 900만 로우의 데이터가 쌓였는데, 사용중인 DB(postgresql)와 같은 칼럼이 존재해서 선택도가 100%로 나오지 않는 이상, 대부분이 매우 낮은 선택도가 나오게 된다. (100%의 선택도는 사실상 풀스캔... 인덱싱하면서 오버헤드만 잡아먹음..) 인덱싱 걸린 칼럼 내 값 기준으로 어쨌든 서칭 범위를 좁혀 주기에 WHERE절에서 많이 활용하는 칼럼은 인덱싱 해주는게 실 효과가 좋았다. (비교 테스트 완료)

 

아직 개념이 부족한 부분이 많아서 추가적인 수정이 들어갈 수 있을 것 같다.

 

추가적으로 인덱싱 시 주요하게 활용한 지표들의 개념은 아래와 같다.
  • 카디널리티 - 특정 데이터 집합의 유니크한 값의 개수
  • 선택도 - 특정 id값 감안 시, 약 6천개의 특정 값 → 6000 / 9million = 0.000666...
  • 활용도 - 말그대로 조건절 등에서 자주 활용되는 칼럼
  • 전체 데이터 로우 수 - 9m.. → 월 별 파티셔닝이 적용되어 있지만 향후 범위 넓게 조회 시 수천만~수억

 

 
*인덱싱 관련 아래 인프런 질문&답변 링크와 함께 연결된 원문 링크에서 매우 큰 도움을 받았다.

 

Comments