입력 데이터 및 데이터 소스 관리

입력 데이터를 평가할 때는 필수 I/O를 고려해야 합니다. 쿼리에서 읽는 바이트 수는 얼마인가요? 입력 데이터 양을 적절하게 제한하고 있나요? 데이터가 기본 BigQuery 저장소에 있나요? 아니면 외부 데이터 소스에 있나요? 쿼리에서 읽는 데이터 양과 데이터 소스는 쿼리 성능과 비용에 영향을 미칩니다.

쿼리에서 입력 데이터를 읽는 방법은 쿼리 계획 설명에서 확인할 수 있습니다.

다음 권장사항에서는 입력 데이터 관리 및 데이터 소스 선택에 관한 지침을 제공합니다.

투영 관리 - SELECT * 사용 피하기

권장사항: 투영 관리 — 필요한 열만 쿼리합니다.

투영은 쿼리가 읽은 열의 수를 나타냅니다. 열을 과도하게 투영하면 불필요한 I/O 추가 및 구체화(결과 작성)가 발생합니다.

SELECT * 사용은 데이터를 쿼리하는 가장 비용이 많이 드는 방법입니다. SELECT *를 사용하면 BigQuery가 테이블의 모든 열을 전체 스캔합니다.

데이터를 실험 또는 탐색하는 경우에는 SELECT * 대신 데이터 미리보기 옵션 중 하나를 사용합니다.

SELECT * 쿼리에 LIMIT 절을 적용해도 쿼리가 읽는 데이터 양은 달라지지 않습니다. 전체 테이블에서 읽은 모든 바이트에 대해 요금이 청구되며 무료 등급 할당량에서 쿼리가 계산됩니다.

대신 필요한 열만 쿼리합니다. 예를 들어, SELECT * EXCEPT를 사용하면 결과에서 열을 한 개 이상 제외할 수 있습니다.

테이블의 모든 열을 쿼리하되 특정 데이터 하위 집합만 쿼리하고 싶다면 다음 방법을 고려해 보세요.

  • 대상 테이블에서 결과를 구체화하고 해당 테이블을 대신 쿼리합니다.
  • 날짜별로 테이블의 파티션을 나누고 관련 파티션을 쿼리합니다. 예를 들어 WHERE _PARTITIONDATE="2017-01-01"은 2017년 1월 1일 파티션만 검사합니다.

데이터 하위 집합을 쿼리하거나 SELECT * EXCEPT를 사용하면 쿼리가 읽는 데이터 양을 대폭 줄일 수 있습니다. 쿼리 결과에 필요한 데이터 I/O 및 구체화 양이 줄어들기 때문에 비용 절감은 물론 성능 개선 효과까지 얻을 수 있습니다.

파티션을 나눈 쿼리 정리

권장사항: 파티션을 나눈 테이블을 쿼리할 때는 _PARTITIONTIME 유사 열을 사용하여 파티션을 필터링하세요.

파티션을 나눈 표를 쿼리할 때는 _PARTITIONTIME 유사 열을 사용하세요. _PARTITIONTIME을 사용하여 데이터를 필터링하면 날짜 또는 날짜 범위를 지정할 수 있습니다. 예를 들어 다음 WHERE 절은 _PARTITIONTIME 유사 열을 사용하여 2016년 1월 1일부터 2016년 1월 31일 사이의 파티션을 지정합니다.

WHERE _PARTITIONTIME
BETWEEN TIMESTAMP("20160101")
    AND TIMESTAMP("20160131")

쿼리는 날짜 범위가 표시하는 파티션의 데이터만 처리하므로 입력 데이터 양이 줄어듭니다. 파티션을 필터링하면 쿼리 성능을 높이고 비용은 줄일 수 있습니다.

가능한 경우 데이터 비정규화

권장사항: BigQuery는 데이터가 비정규화될 때 최고의 성능을 발휘합니다. 별표나 눈송이 스키마와 같은 관계형 스키마를 유지하는 대신 데이터를 비정규화하고 중첩 필드와 반복 필드를 활용하면 성능을 향상시킬 수 있습니다. 중첩 필드와 반복 필드는 관계형(정규화) 스키마를 유지할 때처럼 성능에 영향을 주지 않으면서 관계를 유지할 수 있습니다.

최신 시스템에서는 정규화된 데이터에 따른 스토리지 비용 절감 효과가 크지 않습니다. 비정규화된 데이터는 저장소 비용을 높이지만 이를 상쇄하는 성능상의 이점을 제공합니다 조인에는 데이터 조정(통신 대역폭)이 필요합니다. 비정규화는 데이터를 개별 슬롯에 로컬화하므로 병렬 실행이 가능합니다.

데이터를 비정규화하는 동안 관계를 유지해야 한다면 데이터를 완전히 병합하는 대신 중첩 및 반복 필드를 사용하세요. 관계형 데이터가 완전히 병합되면 네트워크 통신(무작위 섞기)이 쿼리 성능에 악영향을 줄 수 있습니다.

예를 들어 중첩 및 반복 필드를 사용하지 않고 주문 스키마를 비정규화하면 (일대다 관계가 존재하는 경우) order_id처럼 필드별로 그룹화해야 할 수도 있습니다. 무작위 섞기가 동원되기 때문에 데이터 그룹화는 중첩 및 반복 필드를 이용한 데이터 비정규화보다 성능이 떨어집니다.

중첩 및 반복 필드로 데이터를 비정규화해도 성능이 향상되지 않을 수 있습니다. 다음과 같은 사용 사례에는 비정규화를 적용해서는 안 됩니다.

  • 크기가 자주 바뀌는 별표 스키마가 있습니다.
  • BigQuery가 행 수준 변이로 OLTP(온라인 트랜잭션 처리) 시스템을 보완하지만 대체하지는 못합니다.

중첩 및 반복 필드 사용

BigQuery는 완전한 병합 비정규화를 요구하지 않습니다. 중첩 및 반복 필드를 이용해 관계를 유지할 수 있습니다.

  • 데이터 중첩(STRUCT)

    • 데이터를 중첩하면 외부 항목을 인라인으로 표현할 수 있습니다.
    • 중첩 데이터를 쿼리하면 조인을 사용하는 구문과 유사한 '점' 구문을 사용하여 리프 필드를 참조합니다.
    • 중첩된 데이터는 표준 SQL에서 STRUCT 유형으로 표현됩니다.
  • 반복 데이터(ARRAY)

    • 모드를 REPEATED로 설정하고 RECORD 유형의 필드를 만들면 관계의 카디널리티가 높지 않은 한 일대다 관계를 인라인으로 유지할 수 있습니다.
    • 반복 데이터가 있으면 셔플링이 필요 없습니다.
    • 반복 데이터는 ARRAY로 표현됩니다. 반복 데이터를 쿼리할 때 표준 SQL에서 ARRAY 함수를 사용할 수 있습니다.
  • 중첩 및 반복 데이터(STRUCTARRAY)

    • 중첩과 반복은 서로를 보완합니다.
    • 예를 들어 트랜잭션 레코드 테이블에 항목 STRUCT 배열을 넣을 수 있습니다.

외부 데이터 소스의 적절한 사용

권장사항: 쿼리 성능이 가장 중요하다면 외부 데이터 소스를 사용하지 마세요.

BigQuery에서 관리하는 스토리지에 있는 테이블을 쿼리하는 것은 Google Cloud Storage, Google 드라이브, Google Cloud Bigtable에 있는 외부 테이블을 쿼리하는 것보다 훨씬 빠릅니다.

외부 데이터 소스는 다음 사용 사례에 적용하세요.

  • 데이터를 로드할 때 추출, 변환 및 로드(ETL) 작업 수행
  • 자주 변경되는 데이터
  • 주기적 로드(예: Cloud Bigtable에서 반복적으로 발생하는 내부 데이터화)

과도한 와일드 카드 테이블 사용 피하기

권장사항: 와일드 카드 테이블을 쿼리할 때는 가능한 가장 세분화된 프리픽스를 사용하세요.

와일드 카드를 이용하면 간결한 SQL 구문으로 여러 테이블을 쿼리할 수 있습니다. 와일드 카드 테이블은 와일드 카드 표현식과 일치하는 테이블의 모음입니다. 와일드 카드 테이블은 데이터세트에 다음 요소가 있을 때 유용합니다.

  • 호환되는 스키마가 있고 이름이 유사한 여러 개의 테이블
  • 분할된 테이블

와일드 카드 테이블을 쿼리할 때는 공통 테이블 프리픽스 다음에 와일드 카드(*)를 지정합니다. 예를 들어 FROM bigquery-public-data.noaa_gsod.gsod194*는 1940년대의 모든 테이블을 쿼리합니다.

더욱 세분화된 프리픽스 성능이 짧은 프리픽스보다 우수합니다. 예를 들어 FROM bigquery-public-data.noaa_gsod.gsod194*FROM bigquery-public-data.noaa_gsod.*에 비해 와일드 카드와 일치하는 테이블이 더 적기 때문에 성능이 우수합니다.

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

도움이 필요하시나요? 지원 페이지를 방문하세요.