# 쿼리 최적화

BigQuery는 기본적으로 데이터 처리 능력이 뛰어난 데이터 웨어하우스지만, 쿼리를 어떻게 작성하냐에 따라 성능이 달라집니다.



# JOIN 최적화

# Broadcast Join

  • 방법 : 제일 큰 Table을 Left에 두고 Right에 가장 작은 Table을 위치해서 Broadcast Join 실행

데이터를 JOIN할 때 순서가 매우 중요합니다. 가장 많은 Row를 가지고 있는 Table을 먼저 배치한 후(LEFT), 그 다음 가장 적은 수의 Row를 가지는 Table을 배치하는 경우 Broadcast Join을 실행합니다.

브로드캐스트 조인은 작은 Table이 큰 Table을 처리하는 Slot으로 전송되는 Join입니다. 작은 Table의 데이터가 큰 Table의 데이터가 저장된 Slot으로 이동하니 시간이 적게 소요됩니다.

브로드캐스트 조인을 먼저 진행하는 것이 좋습니다.

TIP

만약 Broadcast Join이 실행되지 않으면 Shuffled Join이 실행됩니다. Shuffled Join은 매우 큰 JOIN이고, 연산이 많이 소요됩니다.



# Hash Join

두 큰 테이블을 JOIN할 경우 BigQuery나 Hash 또는 Shuffle 하며 일치하는 키가 동일한 슬롯에 위치되도록 만든 후, 조인합니다.

데이터를 이동하느라 시간이 많이 소요됩니다.

이런 경우 Clustering (opens new window)을 한다면 Hash Join의 속도를 높일 수 있습니다.

클러스터링 된 테이블은 데이터를 셔플링하는 것과 동일한 효율을 보이기 때문에 사용되곤 합니다.



# Self Join

Self Join은 자신과 자신이 Join되는 경우입니다. 이런 경우는 시간이 많이 소요되는 작업일 수 있고, 여러 곳에서 데이터를 가져와야 하므로 데이터가 더 많이 필요하게 됩니다.

Analytics Function(Window Function)을 사용해 원하는 것을 얻을 수 있다면, 윈도우 함수를 사용하시는 것도 좋습니다.



# Cross Join

Cross Join은 두 Table을 크로스하기 때문에 일반적으로 결과가 매우 큰 Table입니다. WHERE 조건 등이 없다면 기존 Table보다 몇 배의 규모가 생성되기 때문에 실행이 되지 않을 수 있습니다.

미리 집계가 가능하다면 미리 집계를 하거나, 배열을 사용하시면 좋습니다.

UNNEST를 사용하는 쿼리는 Cross Join을 사용하는 형태입니다.

Analytics Function(Window Function)을 사용해 원하는 것을 얻을 수 있다면, 윈도우 함수를 사용하시는 것도 좋습니다.



# Skewed Join

Table의 크기가 극단적으로 불균형할 때 발생할 수 있는 Join입니다. 이런 경우 비대칭으로 인해 데이터 전송도 많이 발생합니다.

데이터를 미리 WHERE 조건으로 필터링하거나, 쿼리를 2개로 쪼개서 별도로 실행하는 것을 추천합니다.



# * 피하기

*은 모든 컬럼을 의미합니다. 필요한 컬럼만 명시할 경우, 딱 필요한 컬럼만 탐색해서 출력하지만 *을 사용한 경우 모든 컬럼을 탐색해야 하기 때문에 속도가 느려집니다. 그리고 모두 사용하지 않으면 비용 관점에서도 사용할 컬럼만 명시하는게 중요합니다.

만약 많은 컬럼을 반환해야 하는 경우, SELECT * EXCEPT를 사용하시면 됩니다



# StandardSQL

2021년 이 시점엔 거의 StandardSQL이 기본 Base지만 2017년도만 해도 legacySQL이 존재했습니다. 2021년 기준 StadnardSQL이 무조건 빠릅니다!

쿼리에서 #standardSQL을 명시하면 이 방식으로 쿼리가 실행됩니다. 요즘은 대부분 이 방식이 Default지만 간혹 과거 API를 사용한다면 LegacySQL을 사용하고 있을 수 있습니다.



# 반복적인 데이터 전처리 피하기

정규 표현식을 사용하거나 SPLIT 함수 등을 한번 진행한 후, 사용하는게 아니라 매번 실행하는 경우 매번 실행하기 때문에 느려집니다.

한번 집계를 한 후, 사용하시는 것을 추천합니다



# Javascript UDF

자바스크립트 UDF는 분명히 유용하지만, 아직 BigQuery에서 속도가 느릴 수 있습니다. 만약 가능하다면 SQL UDF를 사용해주세요



# 참고 자료