Search

tip1 - table sampling

테이블 내 데이터셋이 너무 많아 분석하기 힘들 때 샘플링해줄 수 있다.
크게 두가지 방식이 있는데, RAND() TABLESAMPLE 이다.
rand()
전체 테이블을 스캔해야 하므로 시간 소요 및 비용 발생이 생길 수 있다.
tablesample()
비용 효율적인 테이블 샘플링.
문법적인 구조는 tablesample system(숫자 percent) 를 from 절 테이블 이름 바로 뒤에 위치해주면 된다.
즉, 전체 테이블에서 샘플링할 비율을 정해주는 것이라고 보면 된다.
데이터 블록들로 구성되어 관리되는 빅쿼리 테이블
주의할점
테이블 이름은 영속 테이블(Permanant Table)이나 임시 테이블(Temporary Table)과 같은 Base Table 이어야 하고 이외에 테이블과 동등하게 다루워지는 서브쿼리, View, TVF(Table Valued Function) 또는 UNNEST()가 위치해서는 안된다. 또한 IN 서브쿼리내에서의 사용은 허용되지 않는다.
TABLESAMPLE 절은 테이블이 나뉘어 저장된 여러 데이터 블록 중에 임의의 블럭들을 선택하여 해당 블럭의 모든 행들을 읽어 들인다.
따라서 샘플링의 Granularity(기본단위)가 데이터 블럭의 수에 제한을 받는다. 하나의 데이터 블럭에 저장되는 행의 개수에 의해 결정된다.
→ 데이터 블럭이 가지는 단위 행의 개수(Granularity)에 따라서 원했던 비율의 샘플을 추출하지 못할 수 있으므로 정확한 비율이 필요한 경우에는 LIMIT을 같이 혼용해서 사용할 수 있다.
ex)
SELECT COUNT(1) AS cnt FROM ( SELECT * FROM `firebase-public-project.analytics_153293282.events_*` TABLESAMPLE SYSTEM (2 PERCENT) LIMIT 57000; -- 전체 레코드의 1%
SQL
복사
또는 rand() 와 혼용해서 쓰면 된다.
SELECT * FROM dataset.my_table TABLESAMPLE SYSTEM (20 PERCENT) WHERE RAND() < 0.1
SQL
복사
즉, RAND() 함수는 각각의 행에 대해서 샘플링을 할지 말지를 확률적으로 선택하는 방식이라고 한다면, TABLESAMPLE 은 블럭단위로 샘플링을 할지 말지를 결정한다.