- 참조: https://velog.io/@claraqn/고민-컬럼-수에-따른-성능-차이
- 컬럼 수에 따른 테이블 쪼개기
- 각 글마다 반응이 갈림
- 무조건 나누기
- 컬럼 30개까지는 괜찮다
- 데이터 타입에 따라 고민
- 최대 칼럼 개수
- MySQL 8.0 기준으로 최대 4096개의 컬럼 생성 가능
- 권고사항은 따로 없으며, 최대 개수로 생성해도 상관은 없다
- 테이블을 쪼개는 이유
- 테이블 타입이 변경될 때 등 한 테이블에서 재구축(rebuilding) 하는 것이 어렵기 때문
- 컬럼은 많더라도 INSERT시 모든 컬럼에 값이 들어가지 않는다면 공간 낭비도 생길 수 있음
- 결론적으로는 처음 설계단계에서 부터 테이블을 쪼개는 것이 맞음
- 테이블 수직/수평 분할
-
테이블 수직 분할
수직 분할 예시
테이블 페이지 예시
- 테이블 수직 분할은 칼럼을 기준으로의 분할
- 컬럼이 많아지면 로우 체이닝과 로우 마이그레이션이 많아져서 성능 저하
- 로우 체이닝: 길이가 너무 커서 하나의 블록(페이지)에 저장되지 못하고 다수의 블록에 나누어서 저장됨
- 로우 마이그레이션: 수정된 데이터를 해당 데이터 블록에 저장하지 못하고 다른 블록의 빈 공간에 저장
- 개선: 수많은 컬럼을 동시에 조회하는 경우는 드물게 일어남, 각 조건에 맞게 이용되는 컬럼들로 그룹을 묶어 테이블 분할(용도에 맞는 컬럼끼리 테이블 분할)
-
테이블 수평 분할
수평 분할 예시
- 대량의 데이터가 하나의 테이블에 있으면 인덱스 정보 생성 시 부하가 커짐
- 인덱스를 찾아가는 깊이(depth)가 깊어지고, 인덱스 크기가 커질수록 성능 저하
- 논리적으로는 같은 테이블이지만 물리적으로 서로 다른 여러개의 테이블 스페이스에 나눠서 저장하는 파티션 방법
- 컬럼수 증가에 따른 성능
- 컬럼을 늘릴 때 인덱스를 생성하더라도 인덱스를 참조하여 레코드 전체를 읽기 때문에 많은 컬럼에 대해 I/O가 발생하게 됨
- 즉, DB 컬럼은 linked List로 되어 있어, 인덱스를 활용하더라도 해당열 전체 값을 가져오기 때문에 컬럼이 늘수록 조회 비용은 커짐(참조: ‣)
- 만약 컬럼이 많더라도 INT형인 경우 비교적 작은 데이터를 다루기 때문에 문제가 되지 않을 수 있지만, VARCHAR/TEXT 등의 자료형은 비교적 큰 데이터를 다루기 때문에 문제가 될 수 있음
- VARCHAR 자료형의 경우 컬럼이 100개를 넘어가면 성능 저하가 발생함(INT/CHAR 등은 큰 성는 저하는 없음)