컬럼형 저장
컬럼형 저장
Amazon Redshift가 테이블 데이터를 저장하는 방식, 컬럼형 저장을 살펴볼게요. 분석 쿼리가 빨라지는 첫 번째 비결이 바로 여기 있어요. 일반적인 관계형 데이터베이스가 행 단위로 블록에 저장하는 것과 달리, 컬럼 단위로 같은 타입의 값들을 모아 저장하면 디스크에서 읽어야 할 양 자체가 확 줄어들어요. 디스크 I/O가 줄어드는 게 쿼리 성능에 얼마나 중요한지는 직접 경험해 보면 체감이 클 거예요.
출처: https://docs.aws.amazon.com/redshift/latest/dg/c_columnar_storage_disk_mem_mgmnt.html
행 방식 저장과의 차이
전형적인 관계형 테이블에서는 한 행이 곧 한 레코드의 모든 필드 값을 담아요. 행 방식(row-wise) 저장은 그 행 전체를 구성하는 각 컬럼 값을 순서대로 한 블록에 쌓아 두는 방식이에요. 레코드 크기가 블록보다 크면 한 레코드를 저장하는 데 블록이 여러 개 필요해지고, 반대로 블록이 크면 한 레코드를 저장하고도 공간이 남아 비효율적이 돼요.
OLTP(온라인 트랜잭션 처리) 애플리케이션은 보통 레코드 한 건 또는 소수의 레코드에 대해 행 전체를 자주 읽고 쓰기 때문에, 이런 행 방식 저장이 이상적이에요. 트랜잭션이 한 행의 거의 모든 컬럼을 건드리는 경우가 많으니까요.
컬럼형 저장은 여기서 방향이 달라요. 각 컬럼의 값들을 컬럼별로 블록에 연속해서 쌓아 둬요. 그러면 한 데이터 블록이 여러 행에 걸친 단일 컬럼의 값들만 담게 돼요. 데이터가 시스템에 들어오면 Amazon Redshift는 각 컬럼을 컬럼형 저장으로 자동 변환하니까, 사용자가 저장 방식을 직접 신경 쓸 필요는 없어요.
왜 I/O가 줄어들까
간단한 예로 생각해 볼게요. 컬럼형 저장에서 한 블록이 담는 레코드 수는 행 방식보다 훨씬 많아요. 그래서 같은 수의 컬럼 값을 같은 수의 레코드에서 읽으려면 I/O 횟수가 크게 줄어요. 컬럼 수가 많고 행 수도 아주 많은 테이블일수록 이 절감 효과는 비례해서 커져요.
게다가 각 블록이 같은 타입의 데이터만 담으니, 그 컬럼의 데이터 타입에 맞는 압축 방식을 골라 적용할 수 있어요. 그래서 디스크 공간과 I/O가 한 번 더 줄어들죠. 이런 압축 절감은 디스크에 저장할 때뿐 아니라 디스크에서 읽어 메모리에 올릴 때도 그대로 이어져요.
분석 쿼리는 대부분 수많은 행에서 소수의 컬럼만 읽어요. 예를 들어 100개의 컬럼이 있는 테이블에서 쿼리가 5개 컬럼만 쓴다면, 테이블 데이터의 약 5퍼센트만 읽으면 돼요. 이 절감이 수십억, 수조 건의 레코드에 대해 반복되니 누적 효과는 어마어마해요. 반면 행 방식 데이터베이스는 필요 없는 95개 컬럼이 든 블록까지 함께 읽어야 해요.
한 가지 재미있는 차이는 블록 크기예요. 일반적인 데이터베이스의 블록 크기는 2KB에서 32KB 정도인데, Amazon Redshift는 1MB 블록을 써요. 블록이 크면 로드나 다른 작업에서 필요한 I/O 요청 횟수가 더 줄어들어서 효율이 올라가요.