Preparing your data files

Preparing your data files (데이터 파일 준비)

이 주제는 로딩을 위한 데이터 파일을 준비하기 위한 모범 사례, 일반 지침, 중요한 고려 사항을 제공해요.

출처: Snowflake Documentation

본문

파일 크기 모범 사례

최상의 로드 성능을 얻고 크기 제한을 피하려면 다음 데이터 파일 크기 지침을 고려해요. 이 권장 사항은 벌크 데이터 로드와 Snowpipe를 사용한 연속 로딩 둘 다에 적용된다는 점을 주목해요.

일반 파일 크기 권장 사항

병렬로 실행되는 로드 작업 수는 로드할 데이터 파일 수를 초과할 수 없어요. 로드의 병렬 작업 수를 최적화하려면 압축된 대략 100-250MB(또는 더 큰) 크기의 데이터 파일을 만드는 것을 목표로 할 것을 권장해요.

Note

매우 큰 파일(예: 100GB 이상)을 로드하는 것은 권장되지 않아요.

큰 파일을 로드해야 한다면 ON_ERROR 복사 옵션 값을 신중히 고려해요. 작은 수의 오류로 파일을 중단하거나 건너뛰면 지연과 크레딧 낭비가 발생할 수 있어요. 또한 데이터 로딩 작업이 최대 허용 시간인 24시간을 초과해 계속되면 파일의 어떤 부분도 커밋되지 않고 작업이 중단될 수 있어요.

더 작은 파일을 집계해 각 파일의 처리 오버헤드를 최소화해요. 더 큰 파일을 더 많은 수의 더 작은 파일로 분할해 활성 웨어하우스의 컴퓨팅 리소스에 로드를 분산해요. 병렬로 처리되는 데이터 파일 수는 웨어하우스의 컴퓨팅 리소스 양에 의해 결정돼요. 레코드가 청크에 걸쳐지지 않도록 큰 파일을 줄 단위로 분할할 것을 권장해요.

데이터 소스가 더 작은 청크로 데이터 파일을 내보내는 것을 허용하지 않는다면 타사 유틸리티를 사용해 큰 CSV 파일을 분할할 수 있어요.

RFC4180 사양을 따르는 큰 압축되지 않은 CSV 파일(128MB보다 큰)을 로드한다면, MULTI_LINE이 FALSE로, COMPRESSION이 NONE으로, ON_ERROR가 ABORT_STATEMENT 또는 CONTINUE로 설정되었을 때 Snowflake가 이러한 CSV 파일의 병렬 스캔을 지원해요.

Linux 또는 macOS

split 유틸리티를 사용하면 CSV 파일을 여러 개의 더 작은 파일로 분할할 수 있어요.

구문:

split [-a suffix_length] [-b byte_count[k|m]] [-l line_count] [-p pattern] [file [name]]

자세한 내용은 터미널 창에서 man split을 입력해요.

예:

split -l 100000 pagecounts-20151201.csv pages

이 예는 pagecounts-20151201.csv라는 파일을 줄 길이로 분할해요. 큰 단일 파일이 8GB이고 1,000만 줄을 포함한다고 가정해요. 100,000개씩 분할하면 100개의 더 작은 파일 각각이 80MB가 돼요(1천만 / 10만 = 100). 분할 파일은 pages*suffix*로 이름 붙여져요.

Windows

Windows에는 기본 파일 분할 유틸리티가 포함되어 있지 않지만, Windows는 큰 데이터 파일을 분할할 수 있는 많은 타사 도구와 스크립트를 지원해요.

데이터베이스 객체 크기 제한

Snowflake로의 데이터 로딩에 사용 가능한 방법을 사용하면 다음 한도까지의 크기로 객체를 저장할 수 있어요.

데이터 타입 저장 한도
ARRAY 128 MB
BINARY 64 MB
GEOGRAPHY 64 MB
GEOMETRY 64 MB
OBJECT 128 MB
VARCHAR 128 MB
VARIANT 128 MB

VARCHAR 컬럼의 기본 크기는 16MB(binary는 8MB)예요. 16MB보다 큰 컬럼 크기를 가진 테이블을 만들려면 크기를 명시적으로 지정해요. 예:

CREATE OR REPLACE TABLE my_table (
  c1 VARCHAR(134217728),
  c2 BINARY(67108864));

VARCHAR 컬럼에 새 한도를 사용하려면 테이블을 변경해 컬럼 크기를 바꿀 수 있어요. 예:

ALTER TABLE my_table ALTER COLUMN col1 SET DATA TYPE VARCHAR(134217728);

이 테이블의 BINARY 유형 컬럼에 새 크기를 적용하려면 테이블을 다시 만들어요. 기존 테이블의 BINARY 컬럼 길이는 변경할 수 없어요.

ARRAY, GEOGRAPHY, GEOMETRY, OBJECT, VARIANT 유형의 컬럼은 길이를 지정하지 않고도 기존 테이블과 새 테이블에서 기본적으로 16MB보다 큰 객체를 저장할 수 있어요. 예:

CREATE OR REPLACE TABLE my_table (c1 VARIANT);

과거에 만들어졌고 VARIANT, VARCHAR, BINARY 값을 입력으로 사용하는 프로시저와 함수가 있다면 16MB보다 큰 객체를 지원하려면 재생성(길이 지정 없이)해야 할 수 있어요. 예:

CREATE OR REPLACE FUNCTION udf_varchar(g1 VARCHAR)
  RETURNS VARCHAR
  AS $$
    'Hello' || g1
  $$;

외부 관리 Iceberg 테이블의 경우 VARCHAR와 BINARY 컬럼의 기본 길이는 128MB예요. 이 기본 길이는 새로 생성되거나 새로 고쳐진 테이블에 적용돼요. 과거에 만들어진 테이블이 있다면 더 작은 한도가 적용될 수 있어요. 이 테이블들을 새로 고쳐 더 큰 크기 한도를 지원하게 할 수 있어요.

관리형 Iceberg 테이블의 경우 VARCHAR와 BINARY 컬럼의 기본 길이는 128MB예요. 새 크기 한도가 활성화되기 전에 만들어진 테이블은 여전히 이전 기본 길이를 가져요. 이러한 테이블의 VARCHAR 유형 컬럼에 새 크기를 적용하려면 테이블을 다시 만들거나 컬럼을 변경해요. 다음 예는 컬럼을 새 크기 한도를 사용하도록 변경해요:

ALTER ICEBERG TABLE my_iceberg_table ALTER COLUMN col1 SET DATA TYPE VARCHAR(134217728);

이 테이블의 BINARY 유형 컬럼에 새 크기를 적용하려면 테이블을 다시 만들어요. 기존 테이블의 BINARY 컬럼 길이는 변경할 수 없어요.

결과 집합의 큰 객체를 지원하는 드라이버 버전

드라이버는 16MB보다 큰 객체(BINARY, GEOMETRY, GEOGRAPHY는 8MB)를 지원해요. 더 큰 객체를 지원하는 드라이버 버전으로 업데이트해야 할 수 있어요. 다음 드라이버 버전이 필요해요.

드라이버 최소 지원 버전 릴리스 날짜
Snowpark Library for Python 1.21.0 2024년 8월 19일
Snowflake Connector for Python 3.10.0 2024년 4월 29일
JDBC 3.17.0 2024년 7월 8일
ODBC 3.6.0 2025년 3월 17일
Go Snowflake Driver 1.1.5 2022년 4월 17일
.NET 2.0.11 2022년 3월 15일
Snowpark Library for Scala and Java 1.14.0 2024년 9월 14일
Node.js 1.6.9 2022년 4월 21일
Spark connector 3.0.0 2024년 7월 31일
PHP 3.0.2 2024년 8월 29일
Snowflake CLI 3.0.0 2024년 10월 1일
SnowSQL 1.3.2 2024년 8월 12일

더 큰 객체를 지원하지 않는 드라이버를 사용하려고 하면 다음 예와 유사한 오류가 반환돼요:

100067 (54000): The data length in result column <column_name> is not supported by this version of the client.
Actual length <actual_size> exceeds supported length of 16777216.

연속 데이터 로드 — 즉, Snowpipe — 및 파일 크기

Snowpipe는 파일 알림이 전송된 후 일반적으로 1분 안에 새 데이터를 로드하도록 설계되었지만, 정말 큰 파일이거나 새 데이터를 압축 해제·복호화·변환하는 데 비정상적인 양의 컴퓨팅 리소스가 필요한 경우에는 로딩이 훨씬 더 오래 걸릴 수 있어요.

리소스 소비에 더해 Snowpipe에 청구되는 사용량 비용에 내부 로드 큐의 파일을 관리하는 오버헤드가 포함돼요. 이 오버헤드는 로딩을 위해 큐에 대기된 파일 수에 비례해 증가해요. 이 오버헤드 요금은 자동 외부 테이블 새로 고침에 Snowpipe가 이벤트 알림에 사용되므로 청구서에 Snowpipe 요금으로 나타나요.

Snowpipe로 가장 효율적이고 비용 효과적인 로드 경험을 얻으려면 파일 크기 모범 사례에서 권장 사항을 따르는 것이 권장돼요(이 주제에서). 대략 100-250MB 이상의 데이터 파일을 로드하면 오버헤드 요금이 부담되지 않을 정도로 총 로드 데이터 양에 비해 오버헤드 비용이 줄어들어요.

소스 애플리케이션에서 MB 단위 데이터를 축적하는 데 1분 이상 걸린다면 분당 한 번 새(잠재적으로 더 작은) 데이터 파일을 만드는 것을 고려해요. 이 접근 방식은 일반적으로 비용(즉, Snowpipe 큐 관리와 실제 로드에 사용되는 리소스)과 성능(즉, 로드 지연 시간) 사이에 좋은 균형을 이끌어 내요.

분당 한 번보다 더 자주 더 작은 데이터 파일을 만들어 클라우드 저장소에 스테이징하면 다음 단점이 있어요.

  • 스테이징과 데이터 로딩 사이의 지연 시간 감소가 보장되지 않아요.
  • Snowpipe에 청구되는 사용량 비용에 내부 로드 큐의 파일을 관리하는 오버헤드가 포함돼요. 이 오버헤드는 로딩을 위해 큐에 대기된 파일 수에 비례해 증가해요.

다양한 도구가 데이터 파일을 집계하고 배치할 수 있어요. 편리한 옵션 하나는 Amazon Data Firehose예요. Firehose는 원하는 파일 크기(버퍼 크기 라고 함)와 새 파일이 전송되는 대기 간격(이 경우 클라우드 저장소로, 버퍼 간격 이라고 함) 둘 다를 정의할 수 있게 해줘요. 자세한 내용은 Amazon Data Firehose 문서를 참고해요. 소스 애플리케이션이 일반적으로 1분 안에 최적 병렬 처리를 위한 권장 최대치보다 큰 파일을 채울 충분한 데이터를 축적한다면 버퍼 크기를 줄여 더 작은 파일 전달을 트리거할 수 있어요. 버퍼 간격 설정을 60초(최소값)로 유지하면 너무 많은 파일을 만들거나 지연 시간이 증가하는 것을 피하는 데 도움이 돼요.

구분 텍스트 파일 준비

로딩을 위한 구분 텍스트(CSV) 파일을 준비할 때 다음 지침을 고려해요.

  • UTF-8이 기본 문자 집합이지만 추가 인코딩도 지원돼요. ENCODING 파일 형식 옵션을 사용해 데이터 파일의 문자 집합을 지정해요. 자세한 내용은 CREATE FILE FORMAT을 참고해요.
  • 구분 기호 문자를 포함하는 필드는 따옴표(단일 또는 이중)로 묶어야 해요. 데이터가 단일 또는 이중 따옴표를 포함하면 그 따옴표를 이스케이프해야 해요.
  • 캐리지 리턴은 Windows 시스템에서 줄 끝을 표시하기 위해 라인 피드 문자와 함께 일반적으로 도입돼요(\r\n). 캐리지 리턴을 포함하는 필드도 따옴표(단일 또는 이중)로 묶어야 해요.
  • 각 행의 컬럼 수는 일관되어야 해요.

반정형 데이터 파일 및 서브컬럼화

반정형 데이터가 VARIANT 컬럼에 삽입되면 Snowflake는 일정한 규칙을 사용해 가능한 한 많은 데이터를 컬럼 형태로 추출해요. 나머지 데이터는 파싱된 반정형 구조의 단일 컬럼으로 저장돼요.

기본적으로 Snowflake는 테이블당 파티션당 최대 200개 요소를 추출해요. 이 한도를 늘리려면 Snowflake Support에 연락해요.

추출되지 않는 요소

다음 특성을 가진 요소는 컬럼으로 추출되지 않아요.

  • 단일 "null" 값이라도 포함하는 요소는 컬럼으로 추출되지 않아요. 이는 누락된 값(컬럼 형태로 표시됨)을 가진 요소가 아닌 "null" 값을 가진 요소에 적용돼요.

이 규칙은 어떤 정보도 손실되지 않도록 보장해요(즉, VARIANT "null" 값과 SQL NULL 값의 차이가 손실되지 않도록).

  • 여러 데이터 타입을 포함하는 요소. 예:

한 행의 foo 요소는 숫자를 포함해요:

{"foo":1}

다른 행의 같은 요소는 문자열을 포함해요:

{"foo":"1"}

추출이 쿼리에 미치는 영향

반정형 요소를 쿼리하면 Snowflake의 실행 엔진은 요소가 추출되었는지에 따라 다르게 동작해요.

  • 요소가 컬럼으로 추출되었다면 엔진은 추출된 컬럼만 스캔해요.
  • 요소가 컬럼으로 추출되지 않았다면 엔진은 전체 JSON 구조를 스캔한 다음 각 행에 대해 값을 출력하기 위해 구조를 순회해야 해요. 이는 성능에 영향을 줘요.

추출되지 않은 요소의 성능 영향을 피하려면 다음을 수행해요.

  • "null" 값을 포함하는 반정형 데이터 요소를 로드하기 전에 관계형 컬럼으로 추출해요. 또는 파일의 "null" 값이 누락된 값을 나타내고 다른 특별한 의미가 없다면 반정형 데이터 파일을 로드할 때 파일 형식 옵션 STRIP_NULL_VALUES를 TRUE로 설정할 것을 권장해요. 이 옵션은 "null" 값을 포함하는 OBJECT 요소나 ARRAY 요소를 제거해요.
  • 각 고유 요소가 형식에 네이티브한 단일 데이터 타입(예: JSON의 문자열 또는 숫자)의 값을 저장하도록 보장해요.

숫자 데이터 지침

  • 쉼표 같은 내장 문자를 피해요(예: 123,456).
  • 숫자에 소수부가 있으면 소수점으로 정수부와 분리해야 해요(예: 123456.789).
  • Oracle 전용. Oracle NUMBER 또는 NUMERIC 타입은 임의의 배율을 허용하므로 데이터 타입이 정밀도나 배율로 정의되지 않았어도 소수 구성 요소가 있는 값을 받아들여요. 반면 Snowflake에서는 소수 구성 요소가 있는 값을 위해 설계된 컬럼은 소수 부분을 보존하려면 배율로 정의해야 해요.

날짜와 타임스탬프 데이터 지침

  • 날짜, 시간, 타임스탬프 데이터의 지원 형식에 대한 정보는 날짜 및 시간 입출력 형식을 참고해요.
  • Oracle 전용. Oracle DATE 데이터 타입은 날짜 또는 타임스탬프 정보를 포함할 수 있어요. Oracle 데이터베이스에 시간 관련 정보도 저장하는 DATE 컬럼이 있다면 Snowflake에서 DATE가 아닌 TIMESTAMP 데이터 타입으로 매핑해요.

Note

Snowflake는 로드 시 시간 데이터 값을 확인해요. 잘못된 날짜, 시간, 타임스탬프 값(예: 0000-00-00)은 오류를 생성해요.

더 알아보기 (Learn more)