데이터 블로그

Power BI - Venn Diagram by MAQ Software 예제

PowerBI

Venn Diagram by MAQ Software는 벤 다이어그램 형태로 데이터를 표시할 때 사용한다.

원에 표시할 영역은 범례(Legend)에 해당하는 열의 값으로 0, 1을 사용해 제어할 수 있다.



데이터 


Measure

1

0

30

1

1

10

0

1

50


범례로 "남" 열과 "여" 열을 사용할 것이다.

그러면 두 개의 원이 나타난다.


"남", "여" 열의 값이 1, 1 인 두 번째 행은 두 영역이 교차하는 지점(A ∩ B)을 뜻한다.

"남", "여" 열의 값이 1, 0 인 첫 번째 행은 "남"에 해당하는 영역을 뜻한다.

"남", "여" 열의 값이 0, 1 인 세 번째 행은 "여"에 해당하는 영역을 뜻한다.




구성






결과







Power BI - Journey Chart by MAQ Software 예제

PowerBI

Journey Chart by MAQ Software는 계층 정보를 네트워크 형태로 시각화 할 때 사용한다.



데이터 


Category1

Category2

Measure

A

AA

10

A

AB

20

A

AC

15

B

BB

30

B

BC

20

C

CA

15

C

CB

21

C

CC

25



구성





결과







AMAZON REDSHIFT. VACUUM 명령

AWS

VACUUM 명령은 다음의 기능을 수행한다.


기능

  1. 정렬되지 않은 리전의 데이터 테이블 정렬

  2. 삭제된 공간 회수

  3. 인터리브 테이블 인덱스 재지정


세 가지 기능 모두다 성능과 많은 밀접한 관계가 있다. 정렬되지 않은 리전의 데이터 테이블 정렬은 SORT KEY를 통한 데이터 조회 최적화가 이루어 진다. Amazon Redshift는 삭제(갱신)된 데이터를 바로 지우지 않고 삭제된 행으로만 표시하고 그대로 두기 때문에 데이터를 실제로 지우고 줄어든 공간을 회수하는 작업도 VACUUM 명령을 통해 이루어진다.


구문

VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX ]

[ [ table_name ] [ TO threshold PERCENT ] ]


파라미터

  • FULL, SORT ONLY, DELETE ONLY, REINDEX

VACUUM 명령이 수행하는 세 가지 기능을 선택적으로 수행할 수 있도록 파라미터가 제공된다. 파라미터마다 수행되는 기능을 정리하면 아래 표와같다.



작업

옵션

FULL

SORT ONLY

DELETE ONLY

REINDEX

테이블 정렬

O

O

X

O

삭제된 공간 회수

O

X

O

O

인터리브 테이블 인덱스 재지정

X

X

X

O



  • table_name: VACUUM 명령을 수행할 테이블 이름이다. 지정하지 않으면 데이터베이스의 모든 테이블에 대해 수행된다. 다만, REINDEX 파라미터를 사용할 때는 반드시 테이블 이름을 지정해야 한다.


  • TO threshold PERCENT: 지정한 임계값 이상으로 테이블이 정렬되어 있다면 정렬 단계를 생략한다. 지정한 임계값 이상을 목표로 삭제된 공간을 회수한다. 기본값은 95



내 생각

  1. 보통은 FULL로 돌려라. 시간이 너무 오래 걸리면, SORT ONLY, DELETE ONLY로 나눠 실행하면 좋을 듯

  2. 인터리브 테이블의 경우, VACUUM REINDEX를 실행해야 한다. 다만, 엄청난 시간이 걸릴 수 있으므로 시간 제약을 고려해야 한다.

  3. 테이블에 정렬되지 않은 큰 리전이 있는 경우, 전체 복사가 vacuum보다 훨씬 빠르다.


제약/주의사항

  1. 클러스터당 한 번에 하나의 VACUUM 명령만 실행할 수 있다.

  2. 실행중에 디스크 사용량이 (많이) 늘어날 수 있다.

  3. 실행중에 쿼리 성능이 느려질 수 있다. 특히 COPY 같은 쓰기 작업은 피하자. 그리고 짧은 시간이지만 테이블이 단독 잠금에 걸릴 수 있다.

  4. 뭔가 이상하다 싶으면 중단하자.



시스템 테이블


-- 정렬되지 않은 행 수 확인
select "table"
	, size
	, unsorted as unsorted_row_ratio
	, tbl_rows as total_rows
	, tbl_rows * unsorted * 0.01 as unsorted_rows
from svv_table_info

-- 삭제된 행 수 확인
select visible_rows, total_rows - visible_rows as deleted_rows
from
(
	select 
		(select sum(rows) from stv_tbl_perm where name = 'table_name') as total_rows
		, (select count(*) from table_name) as visible_rows 
) as rst

-- VACUUM 진행상황 확인
select * from svv_vacuum_progress

-- VACUUM 실행 이력
select * from svv_vacuum_summary


merge_increments bigint vacuum 작업의 병합 단계를 완료하는 데 필요한 병합 증분의 수.

>> merge_increments 열은 각각의 vacuum 작업을 위해 병합된 데이터 양을 표시

>> 연속적 vacuum 동안 병합 증분의 수가 테이블 크기 증가에 비례하여 증가하는 경우,

>> 기존의 정렬된 리전과 새로 정렬된 리전이 중첩되기 때문에 각각의 vacuum 작업이 다시 병합하는 이 테이블의 행이 증가하고 있음을 나타냄.


elapsed_time bigint Elapsed run time of the vacuum operation (in microseconds).

>> 실행 시간(마이크로 초)


row_delta bigint vacuum 전과 후의 테이블의 총 행 수의 차이.

>> 삭제된 행의 영향


sortedrow_delta bigint vacuum 전과 후의 정렬된 테이블 행 수의 차이.

>> 정렬되지 않은 리전의 행 + 삭제된 행


block_delta integer vacuum 전과 후의 테이블 블록 수의 차이.



AMAZON REDSHIFT. 정렬 키(SORT KEY)의 이해

AWS

정렬 키에서 지정한 열의 순서로 데이터는 정렬된 상태로 테이블에 저장된다. 데이터를 정렬된 형태로 저장하면 읽어야할 데이터를 줄임으로써 쿼리

성능을 향상시킬 수 있다. 예를 들어, 고객번호를 정렬 키로 데이터를 저장한 상태에서, 고객번호 30에서 50 사이의 고객 정보를 조회하고자 하는 상황이라고 하자. 이때 데이터를 읽어가다 고객 번호가 50보다 큰 데이터가 나타나기 시작하면, 나머지 데이터를 다 읽지 않아도 읽기 작업을 멈춰도 된다. 이렇게 읽어야할 데이터를 줄여 성능 향상을 기대할 수 있게된다(실제론 이렇게 동작하지 않는다. 이해를 높기위한 설명으로 실제 동작 방식은 아래에서 정리한다).


일반적인 OLTP 워크로드를 처리하는 관계형 데이터베이스와 달리 Amazon Redshift는 인덱스의 개념이 없기 때문에, 정렬 키는 거의 유일하게 읽어야할 데이터를 줄여줄 수 있는 수단이다. 그래서 성능 관점에서 봤을 때 가장 중요한 몇 가지 요소 중 하나라고 생각한다. 잘만 쓰면 성능을 몇 배로 높일 수 있다. 특히 대용량 테이블에서는 그 효과는 더욱 커진다.


여기서는 정렬 키의 종류와 내부 구조에 대한 내용을 정리한다.



복합(Compound) 정렬 키

redshift sort keys - table compound sorted by column

그림 출처: Redshift Sort Keys – Choosing Best Sort Style



복합 정렬 키는 엑셀에서의 데이터 정렬을 생각하면 된다. 정렬 키로 지정한 첫 번째 열로 먼저 정렬을 한다. 그리고 첫 번째 열 중 같은 값들은 두 번째 열로 다시 정렬하여 저장한다. Amazon Redshift는 열 단위로 데이터를 1MB 블록으로 저장하는데, 각 블록의 최소, 최대 값을 저장해 놓고 해당 블록을 읽을지 말지를 결정한다. 앞의 고객번호 예제를 이야기 하지면, 정확하게는 고객번호가 30에서 50사이의 블록만 읽으면 읽기 작업을 완료할 수 있다.


위 그림의 예제는 c_customer_id와 c_country_id 순서로 복합 정렬 키를 만들었을 때 블록을 그린것이다. 여기서 c_customer_id = 1인 데이터를 요청하면, 첫 번째 블록만 읽어서 사용자 요청에 응답할 수 있다. 나머지 데이터는 안 읽어도 되므로 처리 시간을 단축할 수 있는 것이다. 하지만 두 번째 정렬 키인 c_country_id로는 읽어야할 데이터를 줄일 수가 없다. 만약 c_country_id  = 1인 데이터를 요청하면, 4개의 블록을 모두 읽어야 되므로 성능적 이득은 없다.


이상 복합 정렬 키의 특징을 정리해보면 다음과 같다.


  • WHERE 절에 정렬 키의 첫 번째 열로 데이터를 제한하는 부분이 있으면 읽을 데이터를 줄여준다

  • 정렬 키의 첫 번째 열의 카디널리티 높으면 좋다.

  • WHERE 절에 정렬 키의 첫 번째 열이 없다면 읽어야 할 데이터를 줄여주지 못 한다

  • GROUP BY, ORDER BY 와 같이 정렬이 필요한 작업에 이점이 있다





인터리브(Interleaved) 정렬 키

redshift sort keys - data stored in interleaved manner

그림 출처: Redshift Sort Keys – Choosing Best Sort Style



인터리브 정렬 키는 한마디로 뭐다라고 표현하기가 참 힘들다. 많은 문서에서 대부분 다음과 같이 설명한다. 먼저 살펴보자.


인터리브 정렬 키는 정렬 키에서 각 열, 즉 열의 하위 집합에 똑같은 가중치를 부여합니다 -  Amazon Redshift 정렬 키 선택



인터리브 정렬 키를 정확하게 이해하기 위해서는 z order curve  혹은 z order index 이런 것들을 공부하면 보다 그 구조를 잘 알 수 있게된다. 자세한 내용은 추후에 정리해 보기로 하고, 여기서는 앞의 그림을 통해 인터리브 정렬 키는 어떻게 읽을 데이터를 줄여가는지 살펴보고, 어떤 상황에서 인터리브 정렬 키를 쓰면될지 정리해보자.


먼저 복합 정렬 키와 인터리브 정렬 키의 가장 큰 차이는 첫 번째 정렬 키 열이라도 동일한 값이 여러 데이터 블록에 나뉘어 저장된다는 것이다. 대신 두 번째 정렬 키 열로도 같은 가중치로 데이터 블록이 나뉘어 저장된다. 쉽게 이야기하면, 첫 번째 정렬 키의 일부분과 두 번째 정렬 키의 일부분 부분의 조합으로 데이터 블록을 구성한다. 그래서 정렬 키의 첫 번째 열이든, 두 번째 열이든 상관없이 읽어야할 데이터를 줄여줄 수 있다.


몇 가지 예제로 조건별 읽어야 할 데이터 블록의 위치를 살펴보자. 여기 예제에서도 동일하게 c_customer_id 열과 c_country_id 열의 순서로 인터리브 정렬 키를 정의했다고 가정한다.



WHERE c_customer_id = 3 AND c_country_id  = 104





WHERE c_customer_id = 3




WHERE c_country_id  = 104


이렇게 살펴본바로 인터리브 정렬 키의 가장 큰 특징은 정렬 키를 정의할 때 선언한 두 번째 열로도 읽어야할 데이터를 줄일 수 있다는 것이다.


특징

  • 정렬 키를 이루는 열 순서에 상관없이 WHERE 절에 나타나면 잘 동작한다.

  • GROUP BY, ORDER BY 이점이 없다(전체 블록을 다 읽어 정렬해봐야 한다).

  • VACUUM 작업시 실행 시간이 (매우) 길어질 수 있다.




예제


-- 단일 열에 복합 정렬 키 create table customer ( c_custkey integer not null sortkey, c_name varchar(25) not null, c_address          varchar(25) not null, c_city varchar(10) not null, c_nation varchar(15) not null, c_region varchar(12) not null, c_phone varchar(15) not null, c_mktsegment      varchar(10) not null ) -- 여러 열에 복합 정렬 키 create table customer_comp ( c_custkey integer not null, c_name varchar(25) not null, c_address          varchar(25) not null, c_city varchar(10) not null, c_nation varchar(15) not null, c_region varchar(12) not null, c_phone varchar(15) not null, c_mktsegment      varchar(10) not null ) COMPOUND SORTKEY (c_custkey, c_name) -- 여러 열에 인터리브 정렬 키 create table customer_inter ( c_custkey integer not null, c_name varchar(25) not null, c_address         varchar(25) not null, c_city varchar(10) not null, c_nation varchar(15) not null, c_region varchar(12) not null, c_phone varchar(15) not null, c_mktsegment      varchar(10) not null ) INTERLEAVED SORTKEY (c_custkey, c_name, c_phone)



정렬 키 정보(시스템 테이블)


select * from SVV_TABLE_INFO where "table" in ('customer_inter','customer_comp', 'customer')
select * from PG_TABLE_DEF where tablename in ('customer_inter','customer_comp', 'customer')


Power BI - Horizontal Funnel by MAQ Software 예제

PowerBI

Horizontal Funnel by MAQ Software 시각화는 퍼널 분석(Funnel Analysis)의 결과를 표시할때 사용한다. 퍼널 분석은 단계별로 일어나는 일련의 행위를 시각화하여 문제가 있는 단계를 찾기위해 사용한다.



데이터


Series PrimaryMeasure SecondMeasure
Visit 3000 1500
Login 1000 500
View 700 350
Buy 50 25



구성





결과



Power BI - Gantt Chart by MAQ Software 예제

PowerBI


Gantt Chart by MAQ Software 시각화는 간트차트를 KPI와 함께 표시한다. Power BI의 기본 Gantt Chart 시각화에 비해 진행률은 표시할 수 없다.




데이터


Category Start End DataLabel KPI Tooltip
요구사항 정리 2018-08-01 2018-08-05 10 1 Tooltip1
기획 2018-08-06 2018-08-15 20 2 Tooltip2
개발 2018-08-16 2018-09-15 30 3 Tooltip3
테스트 2018-09-16 2018-09-30 40 4 Tooltip4




구성



    • 서식 - KPI column type 항목의 값을 Indicator로 바꿔 KPI를 값이 아닌 Y, O, R, G 아이콘 형태로 나오도록 함



결과



'PowerBI' 카테고리의 다른 글

Power BI - Journey Chart by MAQ Software 예제  (0) 2018.09.21
Power BI - Horizontal Funnel by MAQ Software 예제  (0) 2018.09.09
Power BI - Dual KPI 예제  (0) 2018.09.08
Power BI - Bullet Chart 예제  (0) 2018.09.08
Power BI Python 통합  (0) 2018.09.05

Power BI - Dual KPI 예제

PowerBI

Dual KPI는 두 가지 지표를 동시에 보여줄 때 사용한다. 매출과 수익률과 같이 함께 봐야할 지표를 동시에 표시할 때 사용하면 좋을것 같다.




데이터


Axis TopValues BottomValues WarningState Top% Bottom%
2018-01-01 100 100 -1 2018-01-01 2018-01-05
2018-01-02 110 105 1 2018-01-01 2018-01-05
2018-01-03 100 100 -1 2018-01-01 2018-01-05
2018-01-04 120 99 1 2018-01-01 2018-01-05
2018-01-05 130 95 -1 2018-01-01 2018-01-05
2018-01-06 100 100 1 2018-01-01 2018-01-05
2018-01-07 140 92 -1 2018-01-01 2018-01-05
2018-01-08 145 97 1 2018-01-01 2018-01-05
2018-01-09 150 90 1 2018-01-01 2018-01-05



구성



    • Warning state: 하나의 값을 입력해야 한다. 값이 음수라면 시각화 개체 왼쪽 하단에 ! 표시로 빨간 아이콘이 표시되며 현재 상태가 경고임을 표시한다.
    • Top - % change start date: TOP VALUES 증감 계산의 시작일이다. 보통 KPI에 표시된 첫 번째 날과 마지막 날의 증감이 TOPVALUES(xx %) 이렇게 표시되는데, 데이터 첫 번째 날이 아닌, 임의의 날부터 비교하길 원한다면 지정한다.
    • Bottom - % change start date:  BOTTOM VALUES 증감 계산의 시작일이다. 이 예제에서는 2018년 1월 5일과 2018년 1월 9일을 비교한다.




결과


Power BI - Bullet Chart 예제

PowerBI

Bullet Chart는 범주별 현 상황을 목표대비로 시각화하기 좋다.




데이터


범주 대상값 최소 개선필요 만족 양호 매우좋음 최대 대상값2
에어컨 100 120 50 72 96 108 132 144 114
TV 50 30 25 18 24 27 33 36 28.5
냉장고 60 50 30 30 40 45 55 60 47.5
세탁기 30 10 15 6 8 9 11 12 9.5



구성



개선 필요, 만족, 양호, 매우 좋음은 설정에서 값에 대한 비율로 설정할 수 있다.




결과



Power BI Python 통합

PowerBI

최근에 Power BI 2018년 8월 업데이트를 적용하고 옵션을 확인하던 도중 미리 보기 기능에 Python 지원이라는 문구가 보였다. 대박!!! 그토록 염원하던 기능인데, 프리뷰지만 지원한다니 간단히 테스트를 하고 결과를 정리한다.


먼저 Power BI Desktop 옵션에서 미리 보기 기능을 보면 Python 지원을 활성화 할 수 있다.





Python 지원을 활성화하면 시각화 개체 목록에 Python 시각적 개체가 추가된다.





다시 Power BI Desktop에서 옵션을 열어보면 Python 관련 설정이 보인다. Python이 설치된 경로와 IDE에 대해 설정을 할 수 있다. Python 버전에 대한 안내는 없지만 3.6 버전에서 잘 동작하였다. Python IDE은 Python 스크립트를 외부 IDE에서 편집할 수 있게 해준다.





Python 시각적 개체를 보고서 안으로 추가해 보았다. 그러니 화면 아래쪽에 스크립트 편집기 영역이 나타났다. 여기서 바로 스크립트를 작성할 수 있다. 아니면 Python IDE에서 설정한 편집기로 작성중인 스크립트를 띄울 수도 있다.





Python 시각적 개체를 보고서에 추가했으니, 데이터를 지정해보자. 영역에 필요한 필드를 끌어놓으면 된다. 여기서는 간단한 회귀분석을 진행해 보기로 했다. 그래서 x, y 값을 CSV 형식으로 저장한 다음 Power BI Desktop에서 불러와 Python 시각적 개체에 입력하였다.





Python 시각적 개체에 데이터를 입력하니 스크립트 편집기에 뭔가 자동으로 입력된다. 주석으로 처리되어 있지만, 그 내용을 보면 앞에서 입력한 x, y 값을 Pandas Dataframe형식의 dataset이라는 변수로 접근할 수 있음을 알 수 있다. 그리고 필요한 스크립트를 작성해서 데이터를 처리하여 쓰라는 이야기이다.


아무 스크립트를 추가하지 않은 상태에서 Python IDE로 지정한 Visual Studio Code에서 스크립트를 열어 보았다. Python 스크립트 편집기 오른쪽 상단에 버튼을 누르면 바로 열수 있다. Visual Studio Code에 나타난 코드는 아래와 같다.



# Prolog - Auto Generated #
import os, matplotlib.pyplot, uuid, pandas
os.chdir(u'C:/Users/…./PythonEditorWrapper_c6f91fe0-401c-464d-a654-b45c8dcd7871')
dataset = pandas.read_csv('input_df_27b4cbee-ac0c-4f53-90c7-ddbc9d297506.csv')

matplotlib.pyplot.figure(figsize=(5.55555555555556,4.16666666666667))
matplotlib.pyplot.show = lambda args=None,kw=None: matplotlib.pyplot.savefig(str(uuid.uuid1()))
# Original Script. Please update your script content here and once completed copy below section back to the original editing window #
##############################

# Epilog - Auto Generated #
os.chdir(u'C:/Users/…./PythonEditorWrapper_c6f91fe0-401c-464d-a654-b45c8dcd7871')




이제 Power BI Desktop의 데이터를 어떻게 Python에서 불러오는지 명확해진다. Power BI Desktop 데이터를 CSV 형식으로 임시 저장소에  저장하고, 그 파일을 Pandas의 read_csv 메소드로 불러와 dataset 이라는 변수로 접근할 수 있게 해주는 것이다. 또한 Matplotlib가 import 된것을 볼 수 있다. 이것만 보면 모든 것을 알 수 있을듯 하다. Pandas로 데이터를 저장하고, 그 결과는 Matplotlib로 뿌려주는 형식이다.




히스토그램

앞에서 불러온 데이터를 Python 시각적 개체에 나타내어 보자. 먼저 간단하게 히스토그램을 출력해 보았다.


코드

import matplotlib.pyplot as plt
 
plt.hist(dataset['x'], bins=10, facecolor='blue', alpha=0.5)
plt.show()




실행결과




Matplotlib을 import 한것을 보았을 때 결과가 Jupyter Notebook 처럼 나오지 않을까 생각을 했었는데, 그 생각이 맞았다. 이 정도면 Python으로 했던 분석을 Power BI 리포트나 대시보드에 통합하는 것이 문제 없겠다는 생각을 했다.



회귀분석

이번 목표는 기본으로 import 되는 패키지 외에 다른 패키지도 지원하는지 보는 것이다. 다른 패키지도 잘 동작한다면, 그야말로 신세계가 열릴 수 있다. 여기서는 scipy 패키지를 이용해 회귀분석을 수행해 보았다. 추가로 Matplotlib에서 한글 출력 문제가 없는지도 함께 보았다. 그리고 print 문으로 출력하면 어딘가 결과가 혹시나 나올가하여 출력도 해보았다.



코드

import numpy as np
import matplotlib.pyplot as plt

from scipy import stats

plt.scatter(dataset['x'], dataset['y'], c='red', alpha=0.5)
slope, intercept, r_value, p_value, std_err = stats.linregress(dataset['x'], dataset['y'])

plt.text(5,250, 'slope: {}'.format(slope))
plt.text(5,235, 'intercept: {}'.format(intercept))
plt.text(5,220, '결정계수: {}'.format(r_value ** 2))
print("p_value:", p_value)

x_val = np.linspace(0.0, 140.0, 1000)
for predic_x in x_val:
    predic_y = slope * predic_x + intercept
    plt.scatter(predic_x, predic_y, c='blue', alpha=0.5)

plt.show()




실행결과




오호라.. 잘 나온다. 근데 역시나 한글이 깨진다. 해결방법은 구글에서 쉽게 찾을 수 있다. 아래와 같이 코드를 수정(추가) 하였다.


import numpy as np
import matplotlib.pyplot as plt

from scipy import stats
from matplotlib import font_manager, rc

font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
rc('font', family=font_name)
 
plt.scatter(dataset['x'], dataset['y'], c='red', alpha=0.5)
slope, intercept, r_value, p_value, std_err = stats.linregress(dataset['x'], dataset['y'])

plt.text(5,250, 'slope: {}'.format(slope))
plt.text(5,235, 'intercept: {}'.format(intercept))
plt.text(5,220, '결정계수: {}'.format(r_value ** 2))
print("p_value:", p_value)

x_val = np.linspace(0.0, 140.0, 1000)
for predic_x in x_val:
    predic_y = slope * predic_x + intercept
    plt.scatter(predic_x, predic_y, c='blue', alpha=0.5)

plt.show()




결과




이제 한글까지 잘 나온다. 더 많은 패키지를 테스트 해보고 싶었지만, 뭔가 다 확인했다는 마음인지 만사가 귀찮아진다. 구글에서 찾아보니 누가 테스트 해본 결과가 있어 왠만한건 다 되겠구나 싶다. Power BI 블로그에 Python Episode 1 – A New hope라는 글을 보면 Seaborn, Altair, Scikit-Learn, FlashText 등을 테스트한 결과를 볼 수 있다. 모두 잘 나온다.


이제 마지막 테스트만 남았다. 지금까지 작업한 내용을 웹으로 게시하여 웹에서도 잘 나오는지 확인하였다. 결과는 아직 안 된다. 물론 추후 정식 서비스가 될 것이다. 아마도 어느 패키지까지 지원할 것인지, 어떤 이는 이것으로 Machine Learning 돌려서 그 결과도 보려고 할테니 리소스 제한은 어떻게 할 것인지 고심이 많을 것이다.





갈수록 Power BI가 마음에 들어진다.

AMAZON REDSHIFT. COPY 명령2 - 최적화

AWS

COPY 명령을 통한 데이터 적재 작업의 최적화 방안을 정리한다.



파일 분할

COPY 명령은 여러 파일에서 병렬로 데이터를 불러올 수 있기 때문에 파일을 분할하여 저장하면 좋다. AWS 공식 문서 데이터를 여러 파일로 분할의 내용을 요약하면 다음과 같다.


  • 클러스터에 있는 조각 수의 배수가 되도록 파일을 분할해라

  • 분할된 파일의 크기를 대략 비슷하게 만들어라


간단하게 dc2.large 인스턴스에서 파일 개수를 달리하면서 데이터 적재 속도를 비교해  보았는데, 그 결과는 아래와 같다. 참고로 dc2.large 인스턴스는 조각(Slice) 수가 2개이므로, 2의 배수로 파일을 분할하여 테스트를 진행했다.


테스트 환경

노드 유형: dc2.large

컴퓨팅 노드 수: 4

데이터 크기(원본): 1.6GB


아래 테스트 결과는 절대적이 아니며, 테스트 환경마다 달라질 수 있으므로 직접 테스트하여 최적의 속도를 보이는 파일 분할 수를 찾기를 권장한다.


파일개수

적재시간(초)

1

64

2

35

4

20

8

19




정렬

여기서 하고자하는 이야기는 두 가지로 요약할 수 있다.


  1. 먼저 COPY 명령을 이용해 읽을 데이터 원본을 미리 정렬해 놓는다.

  2. 정렬 키(Sort key)를 이용한 정렬 작업이 최소화


먼저 COPY 명령으로 데이터가 어떻게 Redshift 테이블에 저장되는지 이해해야 한다.  Redshift 테이블은 정렬된 리전(Sorted region)과 정렬되지 않은 리전(Unsorted region)으로 나눠 데이터를 저장된다. 테이블에 데이터가 최초로 저장되거나 VACUUM 명령으로 테이블의 모든 데이터가 정렬된 상태를 유지할 경우 데이터는 모두 정렬된 리전에 저장되어 있다. 이 상태에서 COPY 명령으로 새로운 데이터가 테이블에 입력되면, 그 데이터는 VACUUM 명령이 실행될 때까지 정렬되지 않은 리전에 저장되어 있다. 정렬되지 않은 리전의 데이터가  읽기 성능을 하락시키는 원인이 되기도 한다.




그림 출처: 병합된 행의 볼륨 관리

위 그림에서 Unsorted Region 위쪽의 3행이 Sorted Region을 나타낸다. 대략적인 테이블의 데이터 저장 구조를 알았으니 하고자하는 두 가지 이야기를 진행할 수 있겠다.


데이터 원본을 미리 정렬

위 그림에서 COPY #1 예제를 보면 입력 데이터는 정렬되지 않았지만, COPY 명령 이후 테이블의 정렬되지 않은 리전에 저장된 모습을 보면 CUSTID로 정렬된 형태인 것을 알 수 있다. 이 이야기는 데이터는 리전은 분리되어 관리되지만, 각 리전의 데이터는 정렬된 형태라는 것이다. 즉, 새로 입력된 데이터도 기존 데이터(정렬된 리전)와 합치지지만 않을 뿐, 정렬된 형태로 저장된다. 따라서 COPY 명령에서 읽을 데이터 원본을 정렬 키로 미리 정렬해 놓으면 COPY 명령에서 정렬 작업을 안 하거나, 최소화 할 수 있을 것이다.


올바른 정렬 키 지정

앞 그림의 예제를 조금 바꿔보자.


입력 데이터

CUSTID

sortkey

DATE


400

08/08/2013

500

08/06/2013

600

08/14/2013


테이블 데이터


CUSTID

sortkey

DATE


100

07/04/2013

200

07/02/2013

300

07/03/2013


이 예제에서 확인할 수 있는 것은, 입력 데이터는 다 정렬되어 있고, 입력 데이터의 모든 정렬 키 값은 테이블에 먼저 입력된 값 보다 크다는 것이다. 쉽게 생각하면 새로 입력되는 데이터를 기존 데이터 뒤에 그냥 붙여 넣어도 문제 없이보인다. 실제로도 그렇게 동작할 수 있다. 이렇게 동작한다면 새로 입력되는 데이터도 정렬할 필요가 없으며, 새로 입력한 데이터를 기존 데이터와 합치기 위해서 정렬할 필요도 없을 것이다. 결국 COPY 명령을 수행하는 속도가 빨라진다.


AWS 문서에서도 다음을 만족하면 COPY 명령으로 입력된 데이터가 테이블의 정렬된 리전에 자동으로 추가된다고 한다.


  • 테이블이 하나의 정렬 열에만 복합 정렬 키를 사용

  • 정렬 열은 NOT NULL

  • 테이블이 100% 정렬되어 있거나 비어 있음

  • 모든 새 행은 삭제 대기 상태인 행을 포함하여 기존 행보다 정렬 순서가 더 높다. 이 인스턴스에서 Amazon Redshift는 정렬 키의 첫 8바이트를 사용하여 정렬 순서를 결정


Redshift의 기본 동작은 새로 입력된 데이터는 정렬되지 않은 리전에 저장되어 있다가, VACUUM  명령이 실행되면 그때 정렬된 리전의 데이터와 합쳐지기 된다.