구체화된 뷰 사용
이 문서에서는 구체화된 뷰 및 사용 방법에 대한 추가 정보를 제공합니다. 이 문서를 읽기 전에 구체화된 뷰 소개 및 구체화된 뷰 만들기를 숙지합니다.
구체화된 뷰 쿼리
일반 테이블 또는 표준 뷰를 쿼리하는 것과 동일한 방식으로 구체화된 뷰를 직접 쿼리할 수 있습니다. 구체화된 뷰를 마지막으로 새로고침한 이후 테이블이 변경되더라도 구체화된 뷰에 대한 쿼리는 뷰의 기본 테이블에 대한 쿼리와 항상 일치합니다. 쿼리는 구체화된 새로고침을 자동으로 트리거하지 않습니다.
필요한 역할
구체화된 뷰를 쿼리하는 데 필요한 권한을 얻으려면 관리자에게 구체화된 뷰(materialized view)의 기본 테이블 및 구체화된 뷰 자체에 대한 BigQuery 데이터 뷰어(roles/bigquery.dataViewer
) IAM 역할을 부여해 달라고 요청하세요.
역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.
이 사전 정의된 역할에는 구체화된 뷰를 쿼리하는 데 필요한 권한이 포함되어 있습니다. 필요한 정확한 권한을 보려면 필수 권한 섹션을 펼치세요.
필수 권한
구체화된 뷰를 쿼리하려면 다음 권한이 필요합니다.
-
bigquery.tables.get
-
bigquery.tables.getData
커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 부여받을 수도 있습니다.
스마트 조정의 이점을 누리려면 쿼리에 이러한 권한이 필요합니다.
BigQuery에서 IAM 역할에 대한 자세한 내용은 IAM 소개를 참조하세요.
증분 업데이트
BigQuery는 캐시된 뷰 데이터를 새 데이터와 결합하여 구체화된 뷰를 사용하면서도 일관성 있는 쿼리 결과를 제공합니다. 단일 테이블 구체화된 뷰의 경우 이 결과는 마지막 새로고침 이후 기본 테이블이 변경되지 않았거나 새 데이터만 추가된 경우에 발생할 수 있습니다. JOIN
뷰의 경우, JOIN
의 왼쪽에 있는 테이블만 데이터를 추가할 수 있습니다. JOIN
의 오른쪽에 있는 테이블 중 하나가 변경된 경우에는 뷰를 증분 방식으로 업데이트할 수 없습니다.
마지막 새로고침 이후 기본 테이블에 업데이트 또는 삭제가 적용되었거나 JOIN
의 오른쪽에 있는 구체화된 뷰의 기본 테이블이 변경된 경우 BigQuery가 자동으로 원래 쿼리로 되돌립니다. 조인 및 구체화된 뷰에 대한 자세한 내용은 조인을 참조하세요. 다음은 업데이트 또는 삭제를 유발할 수 있는 Google Cloud 콘솔, bq 명령줄 도구, API 작업의 예시입니다.
- 데이터 조작 언어(DML)
UPDATE
,MERGE
또는DELETE
문 - 자르기
- 파티션 만료 시간
다음 메타데이터 작업도 구체화된 뷰가 증분 방식으로 업데이트되지 않도록 합니다.
- 파티션 만료 시간 변경
- 열 업데이트 또는 삭제
구체화된 뷰를 증분적으로 업데이트할 수 없는 경우 뷰가 자동 또는 수동으로 새로고침될 때까지 캐시된 데이터가 쿼리에 사용되지 않습니다. 작업에 구체화된 뷰 데이터가 사용되지 않은 이유에 대한 자세한 내용은 구체화된 뷰가 거부된 이유 이해를 참조하세요. 또한 기본 테이블에 테이블의 시간 이동 간격보다 긴 기간 동안 처리되지 않은 변경사항이 누적되어 있는 경우 구체화된 뷰를 점진적으로 업데이트할 수 없습니다.
파티션 정렬
구체화된 뷰가 파티션을 나눈 경우 BigQuery는 나뉜 파티션이 기본 테이블의 파티션을 나눈 열과 정렬되도록 합니다. 정렬은 기본 테이블에서 특정 파티션의 데이터가 구체화된 뷰의 동일 파티션에 영향을 주고 있음을 의미합니다. 예를 들어 기본 테이블에서 20220101
파티션의 행은 구체화된 뷰의 20220101
파티션에만 영향을 줍니다.
구체화된 뷰가 파티션으로 분할된 경우 개별 파티션에 대해 증분 업데이트에 설명된 동작이 발생합니다. 예를 들어 기본 테이블의 한 파티션에서 데이터가 삭제되었으면 BigQuery가 구체화된 뷰의 다른 파티션을 계속 사용할 수 있습니다.
내부 조인이 있는 구체화된 뷰는 기본 테이블 중 하나와만 정렬될 수 있습니다. 정렬되지 않은 기본 테이블 중 하나가 변경되면 전체 뷰에 영향을 줍니다.
스마트 조정
BigQuery는 가능할 때마다 구체화된 뷰를 사용하도록 쿼리를 재작성합니다. 자동 재작성은 쿼리 성능 및 비용을 개선하고 쿼리 결과를 변경하지 않습니다. 쿼리는 구체화된 새로고침을 자동으로 트리거하지 않습니다. 쿼리를 재작성하려면 구체화된 뷰가 다음 조건을 충족해야 합니다.
- 기본 테이블 중 하나와 동일한 데이터 세트에 포함됩니다.
- 쿼리와 동일한 기본 테이블 집합을 사용합니다.
- 읽고 있는 모든 열을 포함합니다.
- 읽고 있는 모든 행을 포함합니다.
스마트 조정 예시
다음 구체화된 뷰 쿼리 예시를 살펴보세요.
SELECT store_id, CAST(sold_datetime AS DATE) AS sold_date SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2021-01-01' AND promo_id IS NOT NULL GROUP BY 1, 2
다음 예시는 쿼리를 보여주고, 이러한 쿼리가 이 뷰를 사용해서 자동으로 재작성된 이유 또는 그렇지 않은 이유를 보여줍니다.
쿼리 | 재작성 여부 | 이유 |
---|---|---|
SELECT SUM(net_paid) AS sum_paid, SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2021-01-01' AND promo_id IS NOT NULL |
아니요 | 이 뷰는 읽고 있는 모든 열을 포함해야 합니다. 뷰에 'SUM(net_paid)'가 포함되지 않습니다. |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2021-01-01' AND promo_id IS NOT NULL |
예 | |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2021-01-01' AND promo_id IS NOT NULL AND customer_id = 12345 |
아니요 | 이 뷰는 읽고 있는 모든 열을 포함해야 합니다. 뷰에 'customer'가 포함되지 않습니다. |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE sold_datetime= '2021-01-01' AND promo_id IS NOT NULL |
아니요 | 이 뷰는 읽고 있는 모든 열을 포함해야 합니다. 'sold_datetime'은 출력이 아니고 'CAST(sold_datetime AS DATE)'가 출력입니다. |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2021-01-01' AND promo_id IS NOT NULL AND store_id = 12345 |
예 | |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2021-01-01' AND promo_id = 12345 |
아니요 | 뷰에 읽고 있는 모든 행이 포함되어야 합니다. 'promo_id'는 출력이 아니므로 뷰에 보다 제한적인 필터를 적용할 수 없습니다. |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2020-01-01' |
아니요 | 뷰에 읽고 있는 모든 행이 포함되어야 합니다. 2021년 이후 날짜의 뷰 필터이지만, 쿼리가 2020년의 날짜를 읽습니다. |
SELECT SUM(net_profit) AS sum_profit FROM dataset.store_sales WHERE CAST(sold_datetime AS DATE) >= '2022-01-01' AND promo_id IS NOT NULL |
예 |
쿼리 재작성 여부 파악
구체화된 뷰를 사용하도록 스마트 조정으로 쿼리가 재작성되었는지 파악하려면 쿼리 계획을 조사합니다. 쿼리가 재작성되었으면 쿼리 계획에 READ my_materialized_view
단계가 포함됩니다. 여기서 my_materialized_view
는 사용된 구체화된 뷰의 이름입니다. 쿼리에서 구체화된 뷰를 사용하지 않은 이유를 이해하려면 구체화된 뷰가 거부된 이유 이해를 참조하세요.
구체화된 뷰가 거부된 이유 이해
구체화된 뷰의 자동 새로고침을 사용 중지했고 테이블에 처리되지 않은 변경사항이 있으면 며칠 동안 쿼리 속도가 빨라질 수 있지만 이후 원래 쿼리로 돌아가기 시작하면 처리 속도가 느려집니다. 구체화된 뷰의 이점을 활용하려면 자동 새로고침을 사용 설정하거나 정기적으로 수동으로 새로고침하고 구체화된 뷰 새로고침 작업이 성공했는지 모니터링합니다.
구체화된 뷰가 거부된 이유를 파악하는 단계는 사용한 쿼리 유형에 따라 다릅니다.
- 구체화된 뷰 직접 쿼리
- 스마트 조정에서 구체화된 뷰 사용을 선택할 수 있는 간접 쿼리
다음 섹션에서는 구체화된 뷰가 거부된 이유를 이해하는 데 도움이 되는 단계를 제공합니다.
구체화된 뷰 직접 쿼리
구체화된 뷰에 대한 직접 쿼리는 특정 상황에서 캐시된 데이터를 사용하지 않을 수 있습니다. 다음 단계는 구체화된 뷰 데이터가 사용되지 않은 이유를 이해하는 데 도움이 될 수 있습니다.
- 구체화된 뷰 사용 모니터링의 단계를 따르고 쿼리의
materialized_view_statistics
필드에서 대상 구체화된 뷰를 찾습니다. chosen
이 통계에 있고 값이TRUE
이면 구체화된 뷰가 쿼리에서 사용된 것입니다.rejected_reason
필드를 검토하여 다음 단계를 확인하세요. 대부분의 경우 구체화된 뷰를 수동으로 새로고침하거나 다음 자동 새로고침을 기다릴 수 있습니다.
스마트 조정으로 쿼리
- 구체화된 뷰 사용 모니터링의 단계를 따르고 쿼리의
materialized_view_statistics
에서 대상 구체화된 뷰를 찾습니다. rejected_reason
을 검토하여 다음 단계를 확인하세요. 예를 들어rejected_reason
값이COST
인 경우 스마트 조정에서 비용 및 성능에 따라 더 효율적인 데이터 소스를 식별한 것입니다.- 구체화된 뷰가 없으면 구체화된 뷰의 직접 쿼리를 시도하고 구체화된 뷰 직접 쿼리의 단계를 따릅니다.
- 직접 쿼리에서 구체화된 뷰를 사용하지 않는 경우 구체화된 뷰의 형태가 쿼리와 일치하지 않습니다. 스마트 조정 및 구체화된 뷰를 사용하여 쿼리를 다시 작성하는 방법에 대한 자세한 내용은 스마트 조정 예시를 참조하세요.
자주 묻는 질문(FAQ)
예약된 쿼리와 구체화된 뷰는 각각 어떤 경우에 사용해야 하나요?
예약된 쿼리는 복잡한 계산을 임의로 일정 간격에 따라 실행하기에 편리한 방법입니다. 쿼리가 실행될 때마다 항상 완전히 실행됩니다. 이전 결과는 사용되지 않으며 쿼리의 컴퓨팅 비용을 모두 지불합니다. 예약된 쿼리는 최신 데이터가 필요하지 않으며, 데이터 비활성에 대한 허용 수준이 높은 경우에 효과적입니다.
구체화된 뷰는 최신 데이터를 쿼리하면서도 이전에 계산된 결과를 재사용함으로써 지연 시간과 비용을 최소화하고 싶을 때 적합합니다.
구체화된 뷰를 의사 색인으로 사용할 수 있으며, 기존 워크플로를 업데이트하지 않고 기본 테이블에 대한 쿼리를 가속화합니다. --max_staleness
옵션을 사용하면 구체화된 뷰에 허용되는 비활성을 정의하여 자주 변경되는 대규모 데이터 세트를 처리할 때 비용을 제어하면서 일관된 고성능을 제공할 수 있습니다.
일반 가이드라인에 따라 가능한 모든 경우에 그리고 임의로 복잡한 계산을 실행하지 않을 때는 구체화된 뷰를 사용하세요.
구체화된 뷰에 대한 일부 쿼리는 수동으로 구체화된 테이블의 동일한 쿼리보다 느립니다. 그 이유는
일반적으로 구체화된 뷰에 대한 쿼리가 동등한 구체화된 테이블의 쿼리만큼 성능이 항상 좋은 것은 아닙니다. 구체화된 뷰는 항상 최신 결과를 반환하고 마지막 뷰 새로고침 이후 기본 테이블의 변경사항을 고려해야 하기 때문입니다.
이 시나리오를 살펴보겠습니다.
CREATE MATERIALIZED VIEW my_dataset.my_mv AS SELECT date, customer_id, region, SUM(net_paid) as total_paid FROM my_dataset.sales GROUP BY 1, 2, 3; CREATE TABLE my_dataset.my_materialized_table AS SELECT date, customer_id, region, SUM(net_paid) as total_paid FROM my_dataset.sales GROUP BY 1, 2, 3;
예를 들어 다음 쿼리를 사용합니다.
SELECT * FROM my_dataset.my_mv LIMIT 10
SELECT * FROM my_dataset.my_materialized_table LIMIT 10
반면, 구체화된 뷰에 대한 집계는 일반적으로 구체화된 테이블에 대한 쿼리만큼 빠릅니다. 예를 들어 다음 쿼리를 사용합니다.
SELECT SUM(total_paid) FROM my_dataset.my_mv WHERE date > '2020-12-01'
SELECT SUM(total_paid) FROM my_dataset.my_materialized_table WHERE date > '2020-12-01'