LanguageManual - 샘플링

LanguageManual - 샘플링 (Sampling)

전체 테이블 대신 데이터의 일부만 샘플링해 조회하고 싶을 때 쓰는 TABLESAMPLE 구문을 설명해요. 버킷 샘플링, 블록 샘플링, 행 단위 샘플링까지 다양한 방식을 살펴봅니다.

출처: 문서

본문

샘플링 구문 (Sampling Syntax)

버킷 테이블 샘플링 (Sampling Bucketized Table)


table_sample: TABLESAMPLE (BUCKET x OUT OF y [ON colname])

TABLESAMPLE 절은 전체 테이블 대신 데이터의 샘플을 조회하는 쿼리를 작성할 수 있게 해줍니다. FROM 절의 어떤 테이블에도 추가할 수 있습니다. 버킷은 1부터 번호가 매겨집니다. colname은 테이블의 각 행을 샘플링할 컬럼을 나타냅니다. colname은 테이블의 비파티션 컬럼 중 하나이거나, 개별 컬럼이 아닌 전체 행에 대해 샘플링한다는 뜻의 **rand()**일 수 있습니다. 테이블의 행은 colname을 기준으로 1부터 y까지 번호가 매겨진 y개의 버킷으로 무작위 '버킷화'됩니다. 버킷 x에 속한 행이 반환됩니다.

다음 예제는 테이블 source의 32개 버킷 중 3번째 버킷입니다. 's'는 테이블 별칭입니다.


SELECT *
FROM source TABLESAMPLE(BUCKET 3 OUT OF 32 ON rand()) s;

입력 프루닝(Input pruning): 보통 TABLESAMPLE은 전체 테이블을 스캔하고 샘플을 가져옵니다. 하지만 그렇게 하면 효율적이지 않습니다. 대신 테이블을 CLUSTERED BY 절로 만들면, 테이블이 해시 파티셔닝/클러스터링되는 컬럼 집합이 지정됩니다. TABLESAMPLE 절에 지정된 컬럼이 CLUSTERED BY 절의 컬럼과 일치하면, TABLESAMPLE은 테이블의 필요한 해시 파티션만 스캔합니다.

예제:

위 예제에서 테이블 'source'가 'CLUSTERED BY id INTO 32 BUCKETS'로 생성되었다면,


    TABLESAMPLE(BUCKET 3 OUT OF 16 ON id)

각 버킷이 (32/16)=2개 클러스터로 구성되므로 3번째와 19번째 클러스터를 선택합니다.

반면 다음 tablesample 절은


    TABLESAMPLE(BUCKET 3 OUT OF 64 ON id)

각 버킷이 (32/64)=1/2 클러스터로 구성되므로 3번째 클러스터의 절반을 선택합니다.

CLUSTERED BY 절로 버킷 테이블을 만드는 방법은 Create Table(특히 Bucketed Sorted Tables)과 Bucketed Tables 문서를 참고하세요.

블록 샘플링 (Block Sampling)

블록 샘플링은 Hive 0.8부터 사용할 수 있습니다. JIRA - https://issues.apache.org/jira/browse/HIVE-2121에서 다룹니다.


block_sample: TABLESAMPLE (n PERCENT)

이렇게 하면 Hive가 입력으로 n% 이상 데이터 크기(반드시 행 수를 의미하진 않음)를 선택할 수 있습니다. CombineHiveInputFormat만 지원되며 일부 특수 압축 형식은 처리되지 않습니다. 샘플링에 실패하면 MapReduce 작업의 입력은 전체 테이블/파티션이 됩니다. HDFS 블록 레벨에서 수행되므로 샘플링 세분성은 블록 크기입니다. 예를 들어 블록 크기가 256MB라면 입력 크기의 n%가 100MB뿐이어도 256MB의 데이터를 얻습니다.

다음 예제에서는 입력 크기 0.1% 이상이 쿼리에 사용됩니다.


SELECT *
FROM source TABLESAMPLE(0.1 PERCENT) s;

때로는 같은 데이터를 서로 다른 블록으로 샘플링하고 싶을 수 있습니다. 시드 번호를 변경하면 됩니다:


set hive.sample.seednumber=<INTEGER>;

또는 사용자가 읽을 총 길이를 지정할 수도 있는데, PERCENT 샘플링과 같은 제한이 있습니다. (Hive 0.10.0 기준 - https://issues.apache.org/jira/browse/HIVE-3401)


block_sample: TABLESAMPLE (ByteLengthLiteral)

ByteLengthLiteral : (Digit)+ ('b' | 'B' | 'k' | 'K' | 'm' | 'M' | 'g' | 'G')

다음 예제에서는 입력 크기 100M 이상이 쿼리에 사용됩니다.


SELECT *
FROM source TABLESAMPLE(100M) s;

Hive는 행 수 기준으로 입력을 제한하는 것도 지원하지만, 위 두 방식과 다르게 동작합니다. 첫째, CombineHiveInputFormat이 필요 없어 네이티브가 아닌 테이블에도 사용할 수 있습니다. 둘째, 사용자가 준 행 수가 각 스플릿에 적용됩니다. 따라서 총 행 수는 입력 스플릿 수에 따라 달라질 수 있습니다. (Hive 0.10.0 기준 - https://issues.apache.org/jira/browse/HIVE-3401)


block_sample: TABLESAMPLE (n ROWS)

예를 들어 다음 쿼리는 각 입력 스플릿에서 처음 10행을 가져옵니다.


SELECT * FROM source TABLESAMPLE(10 ROWS);

더 알아보기 (Learn more)

TABLESAMPLE로 데이터 일부만 빠르게 조회할 수 있어요. BUCKET x OUT OF y 방식은 버킷/클러스터 단위로, PERCENT·ByteLength(100M 등) 방식은 블록 단위로, ROWS 방식은 스플릿마다 행 수로 샘플링합니다. CLUSTERED BY와 조합하면 입력 프루닝으로 효율이 좋아집니다.