구체화된 뷰 작업하기

구체화된 뷰는 쿼리 사양(뷰 정의의 SELECT)에서 파생되고 나중에 사용할 수 있도록 저장되는 사전 계산 데이터 세트입니다. 데이터가 사전에 계산되므로 구체화된 뷰의 쿼리가 뷰의 기본 테이블에 대한 쿼리 실행보다 속도가 더 빠릅니다. 이러한 성능 차이는 쿼리가 자주 실행되거나 충분히 복잡한 경우에 중요할 수 있습니다. 결과적으로, 구체화된 뷰는 부담이 큰 집계, 프로젝션 및 선택 작업, 특히 자주 실행되고 규모가 큰 데이터 세트에서 실행되는 작업의 속도를 향상할 수 있습니다.

참고

구체화된 뷰는 반복적인 공통 쿼리 패턴으로 구성된 워크로드에 대한 쿼리 성능을 향상하도록 설계되었습니다. 그러나 임시 결과를 구체화하기 위해서는 추가 비용 이 소요됩니다. 따라서 이러한 결과를 충분히 자주 재사용하여 비용이 절감되는지 여부를 고려한 후 구체화된 뷰를 생성해야 합니다.

구체화된 뷰를 생성해야 하는 경우 결정하기

구체화된 뷰는 특히 다음의 경우에 유용합니다.

  • 기본 테이블(뷰가 정의된 테이블)에 상대적으로 적은 수의 행 및/또는 열이 쿼리 결과에 포함되는 경우.

  • 쿼리 결과에 다음과 같이 상당한 처리가 필요한 결과가 포함되는 경우.

    • 반정형 데이터 분석.

    • 계산에 오랜 시간이 걸리는 집계.

  • 쿼리는 외부 테이블(즉, 외부 스테이지의 파일에 저장된 데이터 세트)에 위치하며, 기본 데이터베이스 테이블 쿼리에 비해 성능이 느릴 수 있습니다.

  • 뷰의 기본 테이블은 자주 변경되지 않습니다.

구체화된 뷰의 이점

Snowflake의 구체화된 뷰 구현에서 제공되는 여러 고유한 속성은 다음과 같습니다.

  • 구체화된 뷰는 동일한 하위 쿼리 결과를 반복적으로 사용하는 쿼리의 성능을 향상할 수 있습니다.

  • Snowflake가 구체화된 뷰에 대한 유지 관리를 자동으로 투명하게 수행합니다. 기본 테이블이 변경된 후 구체화된 뷰는 백그라운드 서비스를 통해 업데이트됩니다. 이러한 방식은 애플리케이션 수준에서 구체화된 뷰에 해당하는 항목을 유지 관리하는 것보다 효율적이며 오류 발생 가능성이 감소합니다.

  • 구체화된 뷰를 통해 액세스되는 데이터는 기본 테이블에서 수행되는 DML의 수량과 관계없이 항상 최신 상태를 유지합니다. 구체화된 뷰가 최신 상태가 되기 전에 쿼리가 실행되는 경우 Snowflake는 구체화된 뷰를 업데이트하거나 구체화된 뷰의 최신 부분을 사용하고 기본 테이블에서 필요한 최신 데이터를 검색합니다.

중요

구체화된 뷰의 자동 유지 관리를 위해서는 크레딧이 사용됩니다. 자세한 내용은 이 항목의 구체화된 뷰 비용 섹션을 참조하십시오.

구체화된 뷰 또는 일반 뷰를 생성해야 하는 경우 결정하기

일반적으로 구체화된 뷰 또는 일반 뷰 생성 여부를 결정할 때 사용되는 기준은 다음과 같습니다.

  • 다음 모든 사항에 해당하는 경우 구체화된 뷰를 생성하십시오.

    • 뷰의 쿼리 결과는 자주 변경되지 않습니다. 즉, 거의 항상 뷰의 기본/기본 테이블이 자주 변경되지 않거나 적어도 구체화된 뷰에서 사용되는 기본 테이블 행의 하위 세트가 자주 변경되지 않습니다.

    • 뷰의 결과는 자주 사용됩니다(일반적으로 쿼리 결과 변경보다 훨씬 더 자주 사용됨).

    • 쿼리에서는 많은 리소스가 사용됩니다. 일반적으로 이는 쿼리가 처리 시간이나 크레딧이 많이 사용됨을 의미하지만, 임시 결과를 위해 쿼리에서 많은 저장소 공간이 사용됨을 의미할 수도 있습니다.

  • 다음 항목 중 1개 이상에 해당하는 경우 일반 뷰를 생성하십시오.

    • 뷰의 결과가 자주 변경됩니다.

    • 결과가 자주 사용되지 않습니다(결과 변경 비율에 상태적으로).

    • 쿼리에서 리소스를 많이 사용하지 않으므로 다시 실행하기 위한 비용이 크지 않습니다.

이러한 기준은 단지 지침일 뿐입니다. 자주 사용하지 않는 경우에도 구체화된 뷰는 이점을 제공할 수 있으며, 특히 뷰를 사용하는 것보다 결과의 변경 횟수가 적은 경우에 유용합니다.

또한, 일반 뷰 또는 구체화된 뷰를 사용할지 결정할 때 고려해야 할 다른 요소가 있습니다.

예를 들어, 구체화된 뷰를 저장하기 위해서는 비용이 소요된다는 점이 한 가지 요인이며, 결과가 자주 사용되지 않는 경우에는(변경되는 것보다 더 자주 사용되는 경우도 해당) 성능 향상에 비해 추가 저장소에 소요되는 비용의 가치가 없을 수 있습니다.

테이블, 일반 뷰 및 캐싱된 결과의 비교

구체화된 뷰는 어떤 면에서는 테이블과 유사하고 다른 면에서는 일반(즉, 구체화되지 않은) 뷰와 유사합니다. 또한, 구체화된 뷰는 캐싱된 결과와 몇 가지 유사점이 있으며, 특히 그 이유는 두 경우 모두 향후 재사용을 위해 쿼리 결과를 저장할 수 있기 때문입니다.

이 섹션에서는 다음을 포함하여 특정 영역에서 이러한 오브젝트 간의 유사점과 차이점에 대해 설명합니다.

  • 쿼리 성능.

  • 쿼리 보안.

  • 쿼리 로직 복잡성 감소.

  • 데이터 클러스터링(쿼리 성능 관련).

  • 저장소 및 유지 관리 비용.

Snowflake는 쿼리가 실행된 후 짧은 시간 동안 쿼리 결과를 캐시에 저장합니다. 일부 상황에서 동일한 쿼리가 다시 실행되고 쿼리가 액세스하는 테이블에서 아무 것도 변경되지 않은 경우 Snowflake는 쿼리를 다시 실행하지 않고 단순히 동일한 결과를 반환할 수 있습니다. 이는 가장 빠르고 효율적인 재사용 방법이지만 유연성이 가장 떨어집니다. 자세한 내용은 지속형 쿼리 결과 사용하기 섹션을 참조하십시오.

구체화된 뷰와 캐싱된 쿼리 결과 모두 쿼리 성능에서의 이점을 제공합니다.

  • 구체화된 뷰는 캐싱된 결과보다 유연하지만 일반적으로 캐싱된 결과보다 속도가 느립니다.

  • 구체화된 뷰는 《캐시》(즉, 뷰에 대한 쿼리 결과) 때문에 테이블보다 속도가 빠르며, 데이터가 변경된 경우 변경되지 않은 데이터에 대해 《캐시》를 사용하고 변경된 데이터에 대해 기본 테이블을 사용할 수 있습니다.

일반 뷰는 데이터를 캐시에 저장하지 않으므로 캐시를 통해 성능을 향상할 수 없습니다. 그러나 일부 경우에는 Snowflake에서 보다 효율적인 쿼리 계획을 생성하기 위해서는 뷰가 도움이 됩니다. 또한, 구체화된 뷰와 일반 뷰 모두 행 수준 또는 열 수준에서 데이터를 노출하거나 숨길 수 있도록 하여 데이터 보안을 강화합니다.

다음 테이블은 테이블, 일반 뷰, 캐싱된 쿼리 결과 및 구체화된 뷰 간의 주요 유사점과 차이점을 보여줍니다.

성능 이점

보안 이점

쿼리 로직 간소화

클러스터링 지원

저장소 사용

유지 관리를 위해 크레딧 사용

참고

일반 테이블

일반 뷰

캐싱된 쿼리 결과

데이터가 변경되지 않고 쿼리가 명확한 함수(예: CURRENT_DATE 아님)만 사용하는 경우에만 사용됩니다.

구체화된 뷰

저장소 및 유지 관리 요구 사항에서는 일반적으로 비용이 증가 하게 됩니다.

외부 테이블

데이터는 Snowflake 외부에서 유지되므로 Snowflake에서는 저장소 요금이 발생하지 않습니다.

구체화된 뷰에 대한 사용 사례의 예

이 섹션에서는 구체화된 뷰에 대한 개념적 개요를 제공하는 몇 가지 일반적인 사용 시나리오를 설명합니다.

  • S 하위 쿼리가 포함된 Q 쿼리를 매일 실행한다고 가정해 보겠습니다. S 에서 리소스가 많이 사용되고 일주일에 한 번만 변경되는 데이터를 쿼리하는 경우 S 를 실행하고 이름이 CT 인 테이블에 결과를 테이블에 캐싱하여 외부 쿼리 Q 의 성능을 향상할 수 있습니다.

    • 일주일에 한 번만 테이블을 업데이트합니다.

    • 나머지 시간에는 Q 를 실행하면 테이블에 저장된 S 의 하위 쿼리 결과를 참조하게 됩니다.

    하위 쿼리 S 의 결과가 예측 가능하게 변경(예: 매주 같은 시간)되는 경우에는 올바르게 작동합니다.

    그러나 S 의 결과가 예기치 않게 변경되면 결과를 테이블에 캐싱하는 것은 위험하며, 일부 경우 Q 하위 쿼리의 결과가 오래된 경우(따라서 캐싱된 테이블 CT 의 결과가 오래된 경우) 기본 쿼리 S 에서 최신 상태가 아닌 결과가 반환됩니다.

    이상적으로는 거의 변경되지 않지만 변경 시점을 예측할 수 없는 결과를 위한 특별한 타입의 캐시가 필요합니다. 다른 관점으로 보자면, 필요할 때 S 하위 쿼리를 강제로 다시 실행하고 CT 캐시 테이블을 업데이트할 수 있습니다.

    구체화된 뷰를 사용하면 두 방식의 이점을 활용할 수 있습니다. 구체화된 뷰에 대한 쿼리를 정의하면 쿼리 결과가 캐시에 저장되지만(내부 테이블에 저장되는 것처럼) Snowflake는 구체화된 뷰가 정의된 테이블이 업데이트될 때 캐시를 업데이트합니다. 따라서 하위 쿼리의 결과를 편리하게 사용하여 빠른 성능을 달성할 수 있습니다.

  • 보다 구체적인 예로, 대형 약국의 소규모 지점을 운영하고 있고 해당 지점에 FDA에서 승인된 수만 개의 전체 의약품 중 수백 개의 의약품이 있다고 가정해 보겠습니다.

    또한, 각 고객이 복용하는 모든 의약품의 전체 목록이 있으며 거의 모든 고객이 재고가 있는 약품만 주문(즉, 특별 주문이 거의 없음)한다고 가정해 보겠습니다.

    이 시나리오에서는 재고로 유지하는 의약품의 상호 작용만 나열하는 구체화된 뷰를 생성할 수 있습니다. 고객이 한 번도 사용하지 않은 의약품을 주문할 때 해당 의약품과 고객이 복용하는 다른 모든 의약품이 모두 구체화된 뷰에 포함되는 경우 약물의 상호 작용에 대한 전체 FDA 데이터베이스를 확인할 필요가 없으며, 구체화된 뷰를 확인하기만 하면 되므로 더욱 빠르게 검색할 수 있습니다.

  • 구체화된 뷰만 사용하거나 조인에서 사용할 수 있습니다.

    약국의 예에서, 각 고객이 복용하는 모든 의약품을 나열하는 테이블이 1개 있다고 가정해보겠습니다. 해당 테이블과 의약품 상호 작용의 구체화된 뷰와 결합하면 고객의 현재 의약품 중 새 의약품과 상호 작용할 수 있는 의약품이 무엇인지를 확인할 수 있습니다.

    외부 조인을 사용하면 구체화된 뷰에 포함되었는지의 여부와 관계없이 고객의 모든 의약품을 나열할 수 있으며, 외부 조인에서 현재 의약품이 구체화된 뷰에 없는 것으로 표시되면 전체 의약품 상호 작용 테이블에서 쿼리를 다시 실행할 수 있습니다.

쿼리 최적화 프로그램이 구체화된 뷰를 사용하는 방법

뷰를 사용하기 위해 SQL 문에 구체화된 뷰를 지정할 필요가 없습니다. 쿼리 최적화 프로그램은 기본 테이블이나 일반 뷰에 대한 쿼리를 자동으로 다시 작성하여 구체화된 뷰를 대신 사용할 수 있습니다.

예를 들어, 구체화된 뷰에 기본 테이블을 쿼리하기 위해 필요한 모든 행과 열이 포함되어 있다고 가정해 보겠습니다. 최적화 프로그램은 기본 테이블이 아닌 구체화된 뷰를 사용하도록 쿼리를 다시 작성할 수 있습니다. 이를 통해 특히 기본 테이블에 대량의 과거 데이터가 포함된 경우 쿼리 속도를 크게 높일 수 있습니다.

다른 예로, 다중 테이블 조인에서 최적화 프로그램은 조인 테이블 중 하나에 대해 테이블 대신 구체화된 뷰를 사용할 수 있습니다.

참고

구체화된 뷰가 특정 쿼리의 기본 테이블을 대체할 수 있는 경우에도, 최적화 프로그램은 구체화된 뷰를 사용하지 않을 수 있습니다. 예를 들어, 기본 테이블이 필드에 의해 클러스터된 경우 최적화 프로그램이 파티션을 효과적으로 정리하고 기본 테이블을 사용하여 동등한 성능을 제공할 수 있으므로 최적화 프로그램은 (구체화된 뷰가 아닌) 기본 테이블을 스캔하도록 선택할 수 있습니다.

구체화된 뷰는 하위 쿼리의 데이터 소스로도 사용할 수 있습니다.

최적화 프로그램이 암시적으로 구체화된 뷰를 사용하도록 선택하면 구체화된 뷰가 기본 테이블 대신 EXPLAIN 계획 또는 쿼리 프로필에 나열됩니다. 사용자는 이 정보를 사용하여 기존 구체화된 뷰에서 이점을 얻을 수 있는 쿼리를 실험 및 이해할 수 있습니다.

Snowflake에서의 구체화된 뷰 소개

다음 섹션에서는 구체화된 뷰가 Snowflake에서 표현되는 방식을 설명합니다.

구체화된 뷰를 위한 DDL 명령

구체화된 뷰는 일급 데이터베이스 오브젝트입니다. Snowflake는 구체화된 뷰를 생성 및 유지 관리하기 위한 다음과 같은 DDL 명령을 제공합니다.

구체화된 뷰에서의 DML 연산자

Snowflake는 구체화된 뷰에 대한 표준 DML(예: INSERT, UPDATE, DELETE)를 허용하지 않습니다. Snowflake는 사용자의 구체화된 뷰 자르기를 허용하지 않습니다.

자세한 내용은 이 항목의 구체화된 뷰 작업에 대한 제한 사항 섹션을 참조하십시오.

액세스 제어 권한

구체화된 뷰와 관련한 권한 타입 3가지는 다음과 같습니다.

  • 구체화된 뷰가 포함된 스키마에 대한 권한.

  • 구체화된 뷰 자체에 대한 권한.

  • 구체화된 뷰가 액세스하는 데이터베이스 오브젝트(예: 테이블)에 대한 권한.

표준 명령을 사용하여 구체화된 뷰에 대한 권한을 부여 및 취소할 수 있습니다.

구체화된 뷰의 스키마에 대한 권한

구체화된 뷰에서는 저장소 공간이 사용됩니다. 구체화된 뷰를 생성하려면 구체화된 뷰가 포함된 스키마에 대한 CREATE MATERIALIZED VIEW 권한이 필요합니다. 다음과 유사한 명령문을 실행합니다.

GRANT CREATE MATERIALIZED VIEW ON SCHEMA <schema_name> TO ROLE <role_name>;
Copy

GRANT 문에 대한 자세한 내용은 GRANT <권한> 을 참조하십시오.

구체화된 뷰에 대한 권한

구체화된 뷰는 다른 데이터베이스 오브젝트(테이블, 뷰, UDFs 등)와 같이 역할이 소유하고 다른 역할에 부여할 수 있는 권한을 가집니다.

구체화된 뷰에 대해 부여할 수 있는 권한은 다음과 같습니다.

  • SELECT

구체화되지 않은 뷰와 마찬가지로 구체화된 뷰는 기본 테이블의 권한을 자동으로 상속하지 않습니다. 해당 뷰를 사용해야 하는 역할에는 구체화된 뷰에 대한 권한을 명시적으로 부여해야 합니다.

참고

이러한 규칙의 예외는 쿼리 최적화 프로그램이 구체화된 뷰를 사용하기 위해 기본 테이블에 대한 쿼리를 다시 작성하는 경우입니다(해당 설명은 쿼리 최적화 프로그램이 구체화된 뷰를 사용하는 방법 에서 제공됨). 이러한 경우 사용자는 쿼리 결과에 액세스하기 위해 구체화된 뷰를 사용할 수 있는 권한이 필요하지 않습니다.

구체화된 뷰에서 액세스하는 데이터베이스 오브젝트에 대한 권한

구체화되지 않은 뷰와 마찬가지로 구체화된 뷰에 액세스하는 사용자는 뷰가 참조하는 기본 오브젝트가 아닌 뷰에 대한 권한만 필요합니다.

보안 구체화된 뷰

구체화된 뷰는 보안 뷰일 수 있습니다.

보안 뷰에 대한 대부분의 정보는 보안 구체화된 뷰에 적용됩니다. 보안 구체화된 뷰는 비보안 구체화된 뷰와 몇 가지 차이점이 있습니다. 차이는 다음과 같습니다.

  • 뷰가 안전한지 확인하는 명령입니다.

    • 구체화되지 않은 뷰의 경우 SHOW VIEWS 명령의 출력에서 IS_SECURE 열을 확인합니다.

    • 구체화된 뷰의 경우 SHOW MATERIALIZED VIEWS 명령의 출력에서 IS_SECURE 열을 확인합니다.

보안 뷰에 대한 자세한 내용은 보안 뷰 관련 작업하기 을 참조하십시오.

보안 구체화된 뷰를 생성하는 구문에 대한 설명은 CREATE MATERIALIZED VIEW 에서 제공됩니다.

구체화된 뷰 만들기 및 작업하기

이 섹션에서는 구체화된 뷰 만들기 및 작업하기에 대한 정보를 제공합니다.

구체화된 뷰 생성 계획하기

구체화된 뷰를 생성하는 경우에는 몇 가지 분석을 수행하여 뷰가 필요한지 결정해야 합니다.

  1. 자주 사용하거나 비용이 많이 소요되는 쿼리의 필터, 예측 및 집계를 검사합니다.

  2. 쿼리 프로필 및 EXPLAIN 명령을 사용하여 기존 구체화된 뷰가 자동 쿼리 재작성 기능에서 이미 사용 중인지 확인합니다. 쿼리에 적합한 기존 뷰가 있는 경우에는 새로운 구체화된 뷰를 생성할 필요가 없음을 알 수 있습니다.

  3. 구체화된 뷰를 추가하기 전, 현재 쿼리 비용과 성능을 기록하여 새로운 구체화된 뷰를 생성한 후 차이를 평가할 수 있습니다.

  4. 테이블 클러스터링의 이점이 없는 매우 선택적인 필터가 있는 쿼리를 찾은 경우 동일한 필터를 포함하는 구체화된 뷰는 쿼리가 많은 데이터 스캔을 방지하는 데 도움이 될 수 있습니다.

    유사하게, 집계를 사용하거나 평가하기 위해 매우 큰 비용이 소요되는 식(예: 많은 비용이 소요되는 함수 호출 또는 반정형 데이터에 대한 부담이 되는 작업)을 포함하는 쿼리를 찾은 경우 동일한 식을 사용하는 구체화된 뷰 또는 집계가 이점을 제공할 수 있습니다.

  5. 원래 쿼리에 대해 EXPLAIN 명령을 실행하거나 쿼리를 실행하고 쿼리 프로필을 확인하여 새로운 구체화된 뷰가 사용 중인지 확인합니다.

  6. 결합된 쿼리 구체화된 뷰 비용 을 모니터링하고, 성능 또는 비용 이점이 구체화된 뷰의 유지 관리 비용을 초과하는지 확인합니다.

    기본 테이블의 쿼리 비용도 확인합니다. 최적화 프로그램이 구체화된 뷰를 사용하도록 쿼리를 다시 작성할 수 있는 경우 쿼리 컴파일에 더 많은 시간과 리소스가 소요될 수 있습니다. (최적화된 프로그램에서는 더 많은 사항을 고려해야 합니다.)

  7. 쿼리를 단순화하거나 구체화된 뷰가 향상된 성능을 제공한다는 것을 알고 있는 경우 구체화된 뷰를 항상 직접 참조하는 것이 가능함을 기억해야 합니다. 그러나 대부분의 경우 기본 테이블을 간단히 쿼리할 수 있으며 자동 쿼리 재작성 기능이 이를 수행합니다.

구체화된 뷰 만들기

사용자를 생성하려면 CREATE MATERIALIZED VIEW 명령을 사용합니다. 예를 들어, 이 항목의 기본 예: 구체화된 뷰 만들기 를 참조하십시오.

참고

CREATE MATERIALIZED VIEW 문을 완료하기 위해서는 시간이 오래 걸릴 수 있습니다.

구체화된 뷰가 처음 생성될 때 Snowflake는 CTAS(CREATE TABLE … AS ….) 연산을 수행합니다.

구체화된 뷰를 생성할 때 다음 사항에 유의하십시오.

구체화된 뷰에서 허용되지 않는 열 이름 처리하기

구체화된 뷰에서는 다음 열 이름이 허용되지 않습니다.

  • SYSTEM$ 또는 METADATA$ 로 시작하는 이름

  • $SYS_FACADE$ 를 포함하는 이름

  • 열 이름 SYS_MV_SOURCE_PARTITION

이러한 이름 중 하나를 가진 열을 선택하는 구체화된 뷰를 정의하는 경우 해당 열에 대한 별칭을 정의할 수 있습니다. 예:

CREATE OR REPLACE MATERIALIZED VIEW mv AS
  SELECT SYSTEM$ALPHA AS col1, ...
Copy

기본 테이블 참조하기

가능하면 구체화된 뷰에서 참조되는 기본 테이블에 대해 정규화된 이름을 사용해야 합니다. 이를 통해 기본 테이블을 뷰와 다른 스키마로(또는 그 반대로) 이동하는 것과 같이 뷰를 무효화할 수 있는 변경으로부터 뷰를 격리할 수 있습니다.

기본 테이블의 이름이 정규화되지 않고 테이블이나 뷰가 다른 스키마로 이동되면 참조가 무효화됩니다.

또한 뷰 정의에서 기본 테이블을 두 번 이상 참조하는 경우 기본 테이블에 대한 모든 참조에서 동일한 한정자를 사용해야 합니다. 예를 들어, 정규화된 이름을 사용하는 경우 기본 테이블에 대한 모든 참조가 정규화된 이름을 사용하는지 확인합니다.

쿼리 최적화를 위한 필터 지정하기

구체화된 뷰를 생성할 때 필터를 지정하면(예: WHERE column_1 BETWEEN Y and Z), 최적화 프로그램은 동일한 필터 또는 더 제한적인 필터가 있는 기본 테이블에 대한 쿼리에 구체화된 뷰를 사용할 수 있습니다. 다음은 몇 가지 예입니다.

  • 범위 포함의 간단한 예는 다음과 같습니다.

    이 예에서 쿼리의 필터는 구체화된 뷰의 필터와 일치하지 않습니다. 그러나 쿼리의 필터에서는 구체화된 뷰에 있는 행만 선택하므로 최적화 프로그램은 전체 테이블이 아닌 구체화된 뷰를 스캔하도록 선택할 수 있습니다.

    -- Example of a materialized view with a range filter
    create materialized view v1 as
      select * from table1 where column_1 between 100 and 400;
    
    Copy
    -- Example of a query that might be rewritten to use the materialized view
    select * from table1 where column_1 between 200 and 300;
    
    Copy
  • 이 예는 OR 포함을 보여줍니다. 구체화된 뷰에는 후속 쿼리에 필요한 모든 행이 포함됩니다.

    X 값 또는 Y 값이 있는 모든 행을 포함하는 구체화된 뷰를 정의합니다.

    create materialized view mv1 as
      select * from tab1 where column_1 = X or column_1 = Y;
    
    Copy

    Y 값(구체화된 뷰에 포함됨)만 찾는 쿼리를 정의합니다.

    select * from tab1 where column_1 = Y;
    
    Copy

    위의 쿼리는 내부적으로 다음과 같이 다시 작성됩니다.

    select * from mv1 where column_1 = Y;
    
    Copy
  • 이 예는 OR 포함의 다른 예입니다. 구체화된 뷰 정의에는 명시적인 OR 이 없습니다. 그러나 IN 절은 일련의 OR 식과 동일하므로 최적화 프로그램은 위의 OR 포함 예시를 다시 작성하는 것과 동일한 방식으로 이 쿼리를 다시 작성할 수 있습니다.

    create materialized view mv1 as
      select * from tab1 where column_1 in (X, Y);
    
    Copy

Y 값(구체화된 뷰에 포함됨)만 찾는 쿼리를 정의합니다.

select * from tab1 where column_1 = Y;
Copy

위의 쿼리는 내부적으로 다음과 같이 다시 작성됩니다.

select * from mv1 where column_1 = Y;
Copy
  • 이 예에서는 AND 포함을 사용합니다.

    column_1 = X 인 모든 행이 포함된 구체화된 뷰를 생성합니다.

    create materialized view mv2 as
      select * from table1 where column_1 = X;
    
    Copy

    쿼리를 생성합니다.

    select column_1, column_2 from table1 where column_1 = X AND column_2 = Y;
    
    Copy

    쿼리는 다음과 같이 다시 작성할 수 있습니다.

    select * from mv2 where column_2 = Y;
    
    Copy

    구체화된 뷰의 정의에 따르면 이미 모든 행이 column_1 = X 와 일치해야 하므로 재작성된 쿼리는 column_1 = X 식을 포함할 필요가 없습니다.

  • 다음 예는 집계 포함을 보여줍니다.

    구체화된 뷰의 정의는 아래와 같습니다.

    create materialized view mv4 as
      select column_1, column_2, sum(column_3) from table1 group by column_1, column_2;
    
    Copy

    다음 쿼리에서는 위에 정의된 구체화된 뷰를 사용할 수 있습니다.

    select column_1, sum(column_3) from table1 group by column_1;
    
    Copy

    쿼리는 다음과 같이 다시 작성할 수 있습니다.

    select column_1, sum(column_3) from mv4 group by column_1;
    
    Copy

    다시 작성된 쿼리에서는 열_2에 의한 추가 그룹화를 사용하지 않지만, 다시 작성된 쿼리도 해당 추가 그룹화에 의해 차단되지 않습니다.

구체화된 뷰 만들기에 대한 제한 사항

참고

이러한 제한 사항은 현재 제한 사항이며, 그 중 일부는 향후 버전에서 제거되거나 변경될 수 있습니다.

구체화된 뷰 만들기에 적용되는 제한 사항은 다음과 같습니다.

  • 구체화된 뷰는 단일 테이블만 쿼리할 수 있습니다.

  • 자체 조인을 포함한 조인은 지원되지 않습니다.

  • 구체화된 뷰는 다음을 쿼리할 수 없습니다.

    • 구체화된 뷰.

    • 구체화되지 않은 뷰.

    • UDTF(사용자 정의 테이블 함수).

  • 구체화된 뷰에는 다음을 포함할 수 없습니다.

    • UDFs(이 제한 사항은 외부 함수 등 모든 타입의 사용자 정의 함수에 적용됩니다).

    • 윈도우 함수.

    • HAVING 절.

    • ORDER BY 절.

    • LIMIT 절.

    • SELECT 목록에 없는 GROUP BY 키. 구체화된 뷰의 모든 GROUP BY 키는 SELECT 목록의 일부여야 합니다.

    • GROUP BY GROUPING SETS.

    • GROUP BY ROLLUP.

    • GROUP BY CUBE.

    • 구체화된 뷰 내에서의 하위 쿼리 중첩.

    • MINUS, EXCEPT 또는 INTERSECT 세트 연산자.

  • 구체화된 뷰 정의에서는 여러 개의 집계 함수가 허용되지 않습니다.

    참고

    구체화된 뷰에서 허용되는 집계 함수에도 몇 가지 제한 사항이 있습니다.

    • 집계 함수는 중첩될 수 없습니다.

    • 복잡한 식(예: (sum(salary)/10))에서 사용되는 집계 함수는 쿼리의 가장 바깥쪽 수준에서만 사용할 수 있으며 하위 쿼리 또는 인라인 뷰에서는 사용할 수 없습니다.

      예를 들어, 다음이 허용됩니다.

      create materialized view mv1 as
          select
              sum(x) + 100
            from t;
      
      Copy

      다음은 허용되지 않습니다.

      create materialized view mv2 as
          select
              y + 10
            from (
              select
                sum(x) as y
              from t
            );
      
      Copy
    • DISTINCT는 집계 함수와 결합할 수 없습니다.

    • 구체화된 뷰에서 집계 함수 AVG, COUNT, COUNT_IF, MIN, MAX, SUM은 집계 함수로 사용할 수 있지만 윈도우 함수로는 사용할 수 없습니다. 구체화된 뷰에서 OVER 절과 함께 사용할 수 없는 함수는 다음과 같습니다.

      OVER ( [ PARTITION BY <expr1> ] [ ORDER BY <expr2> ] )
      
      Copy
    • 집계 함수가 하위 쿼리에 있는 경우 구체화된 뷰는 해당 하위 쿼리의 집계된 열의 상단에 식을 생성할 수 없습니다. 다음과 같은 구체화된 뷰 정의를 예로 들어 보겠습니다.

      create or replace materialized view mv1 as
          select c1 + 10 as c1new, c2
              from (select sum(c1) as c1, c2 from t group by c2);
      
      Copy

      《c1 + 10》 식은 하위 쿼리에서 집계 함수 상단의 식이므로 오류 메시지가 발생합니다.

      같음 연산자도 식으로 간주됩니다. 즉, 하위 쿼리에서 집계 함수를 나타내는 열을 사용하는 CASE 식도 허용되지 않습니다.

      이러한 제한 사항을 해결하려면 식 없이 구체화된 뷰를 생성한 후 해당 식을 포함하는 구체화되지 않은 뷰를 생성해야 하며, 그러한 예는 다음과 같습니다.

      create or replace materialized view mv1 as
          select c1, c2
              from (select sum(c1) as c1, c2 from t group by c2);
      
      create or replace view expr_v1 as
          select c1 + 10 as c1new, c2
              from (select c1, c2 from mv1);
      
      Copy
  • 구체화된 뷰에서 사용되는 함수는 명확해야 합니다. 예를 들어 CURRENT_TIME 또는 CURRENT_TIMESTAMP 를 사용하는 것은 허용되지 않습니다.

  • 구체화된 뷰는 세션 수준 매개 변수인 TIMESTAMP_TYPE_MAPPING과 같이 매개 변수 설정에 따라 다른 결과를 생성하는 함수를 사용하여 정의하지 않아야 합니다.

    예를 들어, 뷰가 다음과 같이 정의되었다고 간주해 보겠습니다.

    create materialized view bad_example (ts1) as
        select to_timestamp(n) from t1;
    
    Copy

    TO_TIMESTAMP(n) 에서 반환되는 값의 데이터 타입은 TIMESTAMP_TYPE_MAPPING 매개 변수에 따라 달라지므로, 구체화된 뷰의 내용은 뷰가 생성된 시점의 TIMESTAMP_TYPE_MAPPING 값에 따라 달라집니다.

    구체화된 뷰가 생성되면 각 열을 정의하는 식이 평가 및 저장됩니다. 열 정의가 특정 세션 변수에 종속되고 세션 변수가 변경되면 식이 재평가되지 않고 구체화된 뷰가 업데이트되지 않습니다. 구체화된 뷰가 세션 변수의 특정 값에 종속되고 세션 변수의 값이 변경된 경우 구체화된 뷰에 대한 쿼리가 실패합니다.

    이러한 문제를 방지하려면 세션 변수를 사용하는 값에 식을 강제 적용하지 마십시오. 아래의 예에서는 TIMESTAMP_TYPE_MAPPING 매개 변수와 관계없이 출력을 특정 데이터 타입으로 캐스팅합니다.

    create materialized view good_example (ts1) as
        select to_timestamp(n)::TIMESTAMP_NTZ from t1;
    
    Copy

    이 문제는 구체화된 뷰에만 적용되는 것입니다. 구체화되지 않은 뷰는 현재 매개 변수 설정에 따라 동적으로 출력이 생성되므로 결과가 부실해질 수 없습니다.

  • 구체화된 뷰의 정의에서는 FLATTEN 함수의 출력에서 SEQ 열을 선택할 수 없습니다.

    SEQ 열의 값은 구체화된 뷰에서 선택할 때 어떤 방식으로든 순서가 정렬된다는 보장이 없습니다. 구체화된 뷰 정의에서 이 열을 선택하면 출력이 비결정적일 수 있습니다.

  • Time Travel 기능 을 사용하여 구체화된 뷰를 만들 수 없습니다.

기본 예: 구체화된 뷰 만들기

이 섹션에는 구체화된 뷰를 생성 및 사용하는 기본 예시를 제공합니다.

CREATE OR REPLACE MATERIALIZED VIEW mv1 AS
  SELECT My_ResourceIntensive_Function(binary_col) FROM table1;

SELECT * FROM mv1;
Copy

자세한 예시는 이 항목의 에서 제공됩니다.

구체화된 뷰가 유지되는 방식 이해하기

구체화된 뷰를 생성한 후 구체화된 뷰의 데이터는 백그라운드 프로세스에 의해 자동으로 유지 관리됩니다. 다음 사항을 참고하십시오.

  • 구체화된 뷰의 유지 관리는 백그라운드 프로세스로 수행되며 타이밍은 기본 테이블과 구체화된 뷰의 워크로드를 기반으로 최적으로 유지됩니다.

    • 이 프로세스에서는 기본 테이블에 대한 DML 작업(삽입, 업데이트, 삭제)을 통해 변경된 사항으로 구체화된 뷰를 업데이트합니다.

      또한 기본 테이블의 클러스터링으로 인해 구체화된 뷰가 새로 고쳐질 수도 있습니다. 구체화된 뷰 및 기본 테이블 클러스터링 모범 사례 섹션을 참조하십시오.

    • 기본 테이블에 행이 삽입되면 이 프로세스에서 《새로 고침》 작업을 수행하여 구체화된 뷰에 새 행을 삽입합니다.

    • 기본 테이블에서 행이 삭제되면 이 프로세스는 구체화된 뷰에서 《압축》 작업을 수행하여 구체화된 뷰에서 이들 행을 삭제합니다.

  • 구체화된 뷰를 마지막으로 새로 고친 시간을 확인하려면 SHOW MATERIALIZED VIEWS 명령을 실행하십시오.

    출력에서 REFRESHED_ON 및 BEHIND_BY 열을 확인합니다.

    • REFRESHED_ON 및 COMPACTED_ON 열은 각각 새로 고침 작업과 압축 작업으로 처리된 기본 테이블에 대한 마지막 DML 작업의 타임스탬프를 보여줍니다.

    • BEHIND_BY 열은 구체화된 뷰에 대한 업데이트가 기본 테이블에 대한 업데이트보다 뒤처진 시간을 나타냅니다.

  • 유지 관리가 지연되는 경우, 뷰가 최신 상태일 때 실행될 때보다 쿼리가 더 느리게 실행될 수 있지만 결과는 항상 최신 상태입니다.

    구체화된 뷰의 일부 마이크로 파티션이 최신 상태가 아닌 경우 Snowflake는 해당 파티션을 건너뛰고 기본 테이블에서 데이터를 찾습니다.

  • 백그라운드 프로세스에서 특정 사용자 오류가 발생하는 경우(예: 뷰에 대한 쿼리로 인해 《0으로 나누기》 오류 발생) 해당 프로세스는 구체화된 뷰를 무효화합니다.

    유효하지 않은 구체화된 뷰를 쿼리하면 오류가 발생합니다. 오류 메시지에는 구체화된 뷰가 무효화된 이유가 포함됩니다. 예:

    Failure during expansion of view 'MY_MV':
      SQL compilation error: Materialized View MY_MV is invalid.
      Invalidation reason: Division by zero
    

    이 경우 오류 메시지에 설명된 문제를 해결하고(예: 《0으로 나누기》 오류를 유발하는 행 삭제) ALTER MATERIALIZED VIEW … RESUME 명령을 사용하여 구체화된 뷰를 재개합니다.

구체화된 뷰에서 유지 관리 일시 중단 및 재개하기

구체화된 뷰의 유지 관리와 사용을 일시 중단해야 하는 경우 SUSPEND 매개 변수와 함께 ALTER MATERIALIZED VIEW 명령을 실행하십시오.

ALTER MATERIALIZED VIEW <name> SUSPEND
Copy

뷰의 유지 관리를 일시 중단한 경우 유지 관리를 재개할 때까지 뷰를 쿼리할 수 없습니다.

구체화된 뷰의 유지 관리와 사용을 재개하려면 RESUME 매개 변수와 함께 ALTER MATERIALIZED VIEW 명령을 실행하십시오.

ALTER MATERIALIZED VIEW <name> RESUME
Copy

예를 보려면 구체화된 뷰에 대한 업데이트 일시 중단 를 참조하십시오.

구체화된 뷰에 대한 정보 표시하기

구체화된 뷰에 대한 정보를 제공하는 명령 및 뷰는 다음과 같습니다.

  • SHOW VIEWS 명령은 구체화된 뷰 및 일반 뷰에 대한 정보를 반환합니다.

  • INFORMATION_SCHEMA.TABLES 뷰 는 구체화된 뷰를 보여줍니다. TABLE_TYPE 열은 《MATERIALIZED VIEW》를 보여줍니다. 구체화된 뷰에는 직접 삽입할 수 없기 때문에 IS_INSERTABLE 열은 항상 《NO》입니다.

    참고

    INFORMATION_SCHEMA.VIEWS 뷰 는 구체화된 뷰를 보여주지 않습니다. INFORMATION_SCHEMA TABLES는 구체화된 뷰를 보여줍니다.

구체화된 뷰 작업에 대한 제한 사항

참고

이러한 제한 사항은 현재 제한 사항이며, 그 중 일부는 향후 버전에서 제거되거나 변경될 수 있습니다.

구체화된 뷰를 사용하는 데 적용되는 제한 사항은 다음과 같습니다.

  • 구체화된 뷰가 정의된 기본 테이블과 일관성을 유지할 수 있도록 구체화된 뷰 자체에서는 대부분의 DML 작업을 수행할 수 없습니다. 예를 들어, 구체화된 뷰에 직접 행을 삽입할 수 없습니다(물론 기본 테이블에는 행을 삽입할 수 있음). 허용되지 않는 DML 연산은 다음과 같습니다.

    • COPY

    • DELETE

    • INSERT

    • MERGE

    • UPDATE

    구체화된 뷰 자르기는 지원되지 않습니다.

  • CREATE MATERIALIZED VIEW ... CLONE... 명령을 사용하여 구체화된 뷰를 직접 복제할 수 없습니다. 그러나 구체화된 뷰가 포함된 스키마 또는 데이터베이스를 복제하면 구체화된 뷰가 복제되어 새 스키마 또는 데이터베이스에 포함됩니다.

  • Snowflake에서는 Time Travel 기능 을 사용하여 과거 시점 의 구체화된 뷰를 쿼리할 수 없습니다(예: 구체화된 뷰를 쿼리할 때 AT 절 사용).

    하지만 Time Travel을 사용하여 과거 시점의 구체화된 뷰를 포함하는 데이터베이스나 스키마를 복제할 수 있습니다. 자세한 내용은 구체화된 뷰와 Time Travel 섹션을 참조하십시오.

  • 구체화된 뷰는 Snowflake 리소스 모니터 관련 작업하기 에서 모니터링되지 않습니다.

구체화된 뷰에서 기본 테이블 변경의 영향

다음 섹션에서는 구체화된 뷰가 기본 테이블 변경 사항에 어떤 영향을 받는지 설명합니다.

기본 테이블에 열 추가하기

열이 기본 테이블에 추가되는 경우 해당 새 열은 구체화된 뷰에 자동으로 전파되지 않습니다.

이는 구체화된 뷰가 SELECT * (예: CREATE MATERIALIZED VIEW AS SELECT * FROM table2 ...)로 정의되는 경우에도 마찬가지입니다. 구체화된 뷰의 열은 구체화된 뷰가 정의될 때 정의됩니다. SELECT * 는 구체화된 뷰가 쿼리될 때마다 동적으로 해석되지 않습니다.

혼동을 피하기 위해 Snowflake는 구체화된 뷰의 정의에서 SELECT * 를 사용하지 않는 것을 권장합니다.

참고

기본 테이블에 열을 추가하더라도 해당 기본 테이블에 생성된 구체화된 뷰가 일시 중단되지 않습니다.

기본 테이블에서 열 변경 또는 삭제하기

기존 열이 변경되거나 삭제되도록 기본 테이블이 변경되면 해당 기본 테이블의 모든 구체화된 뷰가 일시 중단되며, 구체화된 뷰를 사용하거나 유지 관리할 수 없습니다. (수정되거나 삭제된 열이 구체화된 뷰의 일부가 아닌 경우에도 마찬가지입니다.)

구체화된 뷰를 RESUME할 수 없습니다. 다시 사용하려면 반드시 다시 생성해야 합니다.

뷰에 대해 같은 권한으로 구체화된 뷰를 다시 만드는 가장 간단한 방법은 다음 명령을 실행하여 만드는 방법입니다.

CREATE OR REPLACE MATERIALIZED VIEW <view_name> ... COPY GRANTS ...
Copy

이것은 다음과 같은 목적으로 별개의 명령을 실행하는 것보다 더 효율적입니다.

  1. 구체화된 뷰를 삭제합니다(DROP MATERIALIZED VIEW).

  2. 구체화된 뷰를 다시 만듭니다(CREATE MATERIALIZED VIEW).

  3. 뷰에 대해 같은 권한을 생성합니다(GRANTREVOKE).

기본 테이블 이름 바꾸기 또는 교환하기

기본 테이블(또는 기본 테이블을 포함하는 스키마 또는 데이터베이스)의 이름을 바꾸거나 교환하면 구체화된 뷰가 구체화된 뷰를 만드는 데 사용된 기본 테이블과 다른 기본 테이블을 가리키게 될 수 있습니다. 다음은 이러한 상황이 발생할 수 있는 상황을 예로 든 것입니다.

  • (ALTER TABLE … RENAME을 통해) 기본 테이블의 이름이 바뀌고 기본 테이블의 원래 이름으로 다른 테이블이 생성되는 경우.

  • (ALTER TABLE … SWAP WITH를 통해) 구체화된 뷰의 기본 테이블이 다른 테이블과 교환되는 경우.

  • 구체화된 뷰의 기본 테이블을 포함하는 스키마 또는 데이터베이스가 DROP, SWAP 또는 RENAME을 통해 이동되는 경우.

이러한 경우 구체화된 뷰가 일시 중단됩니다. 대부분의 경우 뷰를 사용하려면 구체화된 뷰를 다시 만들어야 합니다.

기본 테이블 삭제하기

기본 테이블이 삭제되면 구체화된 뷰가 일시 중단됩니다(자동으로 삭제되지 않음).

대부분의 경우에는 구체화된 뷰를 삭제해야 합니다.

어떤 이유로 기본 테이블을 재생성하고 이전에 있던 것과 동일한 정의로 구체화된 뷰를 다시 생성하려는 경우 먼저 기본 테이블을 재생성한 다음 CREATE OR REPLACE MATERIALIZED VIEW <view_name> ... COPY GRANTS ... 을 사용하여 뷰를 교체합니다. 구체화된 뷰 생성을 위한 모범 사례 테이블을 만들고 데이터를 로드하고 뷰를 만듭니다.

복제된 스키마 및 데이터베이스의 구체화된 뷰

구체화된 뷰가 포함된 스키마 또는 데이터베이스를 복제하면 구체화된 뷰가 복제됩니다.

구체화된 뷰와 해당 기본 테이블을 동시에 복제(동일한 CREATE SCHEMA ... CLONE 또는 CREATE DATABASE ... CLONE 작업의 일부)하는 경우 복제된 구체화된 뷰는 복제된 기본 테이블을 참조합니다.

기본 테이블을 복제하지 않고 구체화된 뷰를 복제하는 경우(예: 테이블이 Database1.Schema1에 있고 뷰가 Database1.Schema2에 있으며 Database1의 전체가 아닌 Schema2만 복제하는 경우) 복제된 뷰는 원래 기본 테이블을 참조합니다.

구체화된 뷰 비용

구체화된 뷰는 저장소 및 컴퓨팅 리소스 모두의 비용에 영향을 줍니다.

  • 저장소: 각 구체화된 뷰에서는 쿼리 결과가 저장되며, 이는 계정의 월간 저장소 사용량에 추가됩니다.

  • 컴퓨팅 리소스: 구체화된 뷰가 최신 상태를 유지하지 못하는 것을 방지하기 위해 Snowflake는 구체화된 뷰의 자동 백그라운드 유지 관리를 수행합니다. 기본 테이블이 변경되면 테이블에 정의된 모든 구체화된 뷰가 Snowflake에서 제공하는 컴퓨팅 리소스를 사용하는 백그라운드 서비스에 의해 업데이트됩니다.

    이러한 업데이트를 위해서는 상당한 리소스가 소비되어 크레딧 사용량이 증가하게 됩니다. 그러나 Snowflake는 실제 리소스 사용량만을 계정에 청구하여 크레딧을 효율적으로 사용할 수 있도록 합니다. 청구는 1초 증분으로 계산됩니다.

구체화된 뷰에서 사용하는 컴퓨팅 시간당 크레딧 수를 알아보려면 Snowflake 서비스 사용 테이블 에서 《서버리스 기능 크레딧 테이블》을 참조하십시오.

요금 예상 및 관리하기

구체화된 뷰의 유지 관리 비용을 예상하기 위한 도구는 없습니다. 일반적으로 비용은 다음에 비례합니다.

  • 각 기본 테이블에 생성된 구체화된 뷰의 수 및 기본 테이블이 변경될 때 각 구체화된 뷰에서 변경되는 데이터의 양. 기본 테이블의 마이크로 파티션에 대한 모든 변경 사항은 이러한 변경 사항이 기본 테이블에서 실행되는 DML 문이나 재클러스터링으로 인한 것인지의 여부와 관계없이 궁극적으로 구체화된 뷰를 유지 관리해야 합니다.

  • 클러스터된 구체화된 뷰의 수. 클러스터링(테이블 또는 구체화된 뷰)의 유지 관리를 위해서는 비용이 추가됩니다.

    기본 테이블과 다르게 구체화된 뷰가 클러스터링되는 경우 기본 테이블에서 변경된 마이크로 파티션의 수보다 구체화된 뷰에서 변경된 마이크로 파티션의 수가 상당히 클 수 있습니다.

    예를 들어, 데이터를 삽입(추가)하여 기본 테이블이 크게 변경되고 클러스터링되지 수행되지 않아 기본 테이블의 대부분이 테이블에 행이 삽입된 순서대로인 경우를 생각해 보겠습니다. 구체화된 뷰가 독립 열(예: 우편 번호)로 클러스터링된 상황을 가정해 보십시오. 기본 테이블에 새 행 100개가 추가되면 해당 행은 1개 또는 2개의 새 마이크로 파티션으로 이동하고 기본 테이블의 다른 마이크로 파티션은 그대로 유지됩니다. 그러나 이러한 행 100개는 클러스터링된 구체화된 뷰에서 마이크로 파티션 100개를 다시 작성해야 할 수 있습니다.

    다른 예시로 삭제를 생각해 보겠습니다. 클러스터링이 수행되지 않은 기본 테이블에서 가장 오래된 행을 삭제하면 가장 오래된 마이크로 파티션만 삭제할 수 있지만, 오래된 순서대로 클러스터링이 수행되지 않은 구체화된 뷰에서는 훨씬 더 많은 수의 마이크로 파티션으로 변경해야 할 수 있습니다.

    (클러스터링 구체화된 뷰에 대한 자세한 내용은 구체화된 뷰 및 클러스터링 참조)

사용자는 생성할 뷰의 수, 생성할 테이블 및 각 뷰의 정의(해당 뷰의 행 및 열 수 포함)를 신중하게 선택하여 구체화된 뷰의 유지 관리 비용을 관리할 수 있습니다.

또한, 구체화된 뷰를 일시 중단하거나 다시 시작하여 비용을 관리할 수도 있지만, 유지 관리를 일시 중단하는 것은 일반적으로 비용 절감 요인이 아니라 비용 지연 요인이 됩니다. 유지 관리 지연 기간이 길어지면 더 많은 유지 관리를 수행해야 합니다.

구체화된 뷰 유지 관리 모범 사례 도 참조하십시오.

구체화된 뷰의 유지 관리 비용이 우려되는 경우, Snowflake는 이 기능을 천천히 시작하고(즉, 선택한 테이블에 몇 개의 구체화된 뷰만 생성) 시간 경과에 따른 비용을 모니터링하는 것을 권장합니다.

비용 보기

구체화된 뷰의 유지 관리 요금은 Snowsight, Classic Console 또는 SQL을 사용하여 확인할 수 있습니다.

Snowsight

적절한 권한을 가진 사용자로서 Admin » Usage 를 선택합니다.

Classic Console

계정 관리자로서 Account Account tab » Billing & Usage 를 선택합니다.

크레딧 비용은 Snowflake에서 제공하는 가상 웨어하우스인 Snowflake logo in blue (no text) MATERIALIZED_VIEW_MAINTENANCE 에서 추적할 수 있습니다.

SQL

다음 중 하나를 쿼리합니다.

  • MATERIALIZED_VIEW_REFRESH_HISTORY 테이블 함수(Snowflake Information Schema).

    예:

    SELECT * FROM TABLE(INFORMATION_SCHEMA.MATERIALIZED_VIEW_REFRESH_HISTORY());
    
    Copy
  • MATERIALIZED_VIEW_REFRESH_HISTORY 뷰 뷰(Account Usage).

    MATERIALIZED_VIEW_REFRESH_HISTORY 뷰에 대해 다음 쿼리를 실행할 수 있습니다.

    쿼리: 구체화된 뷰 비용 기록(일별, 오브젝트별)

    이 쿼리는 구체화된 뷰와 지난 30일간 하루 단위로 나누어 이 서비스를 통해 사용된 크레딧 볼륨의 전체 목록을 제공합니다. 크레딧 사용의 불규칙성 또는 지속적으로 높은 사용량은 추가로 조사해봐야 할 대상입니다.

    SELECT TO_DATE(start_time) AS date,
      database_name,
      schema_name,
      table_name,
      SUM(credits_used) AS credits_used
    FROM snowflake.account_usage.materialized_view_refresh_history
    WHERE start_time >= DATEADD(month,-1,CURRENT_TIMESTAMP())
    GROUP BY 1,2,3,4
    ORDER BY 5 DESC;
    
    Copy

    쿼리: 구체화된 뷰 기록 및 m일 평균

    이 쿼리는 작년에 구체화된 뷰에서 사용된 평균 일일 크레딧을 주 단위로 나누어 보여줍니다. 이는 그 해의 일일 평균 이상을 식별하는 데 도움이 될 수 있으므로 사용량의 급증이나 예상치 못한 변화를 조사할 수 있습니다.

    WITH credits_by_day AS (
      SELECT TO_DATE(start_time) AS date,
        SUM(credits_used) AS credits_used
      FROM snowflake.account_usage.materialized_view_refresh_history
      WHERE start_time >= DATEADD(year,-1,CURRENT_TIMESTAMP())
      GROUP BY 1
      ORDER BY 2 DESC
    )
    
    SELECT DATE_TRUNC('week',date),
      AVG(credits_used) AS avg_daily_credits
    FROM credits_by_day
    GROUP BY 1
    ORDER BY 1;
    
    Copy

참고

리소스 모니터 를 사용하여 가상 웨어하우스 크레딧 사용을 관리할 수 있지만, Snowflake logo in blue (no text) MATERIALIZED_VIEW_MAINTENANCE 웨어하우스 등 Snowflake에서 제공하는 웨어하우스의 크레딧 사용을 관리하기 위한 용도로는 사용할 수는 없습니다.

구체화된 뷰 및 클러스터링

구체화된 뷰에서는 클러스터링 키 정의가 지원되며 많은 상황에서 성능을 향상할 수 있습니다. 그러나 이로 인해 비용도 증가합니다.

구체화된 뷰와 구체화된 뷰가 정의된 기본 테이블을 모두 클러스터링하는 경우, 기본 테이블을 클러스터링하기 위해 사용된 열과 다른 열에 구체화된 뷰를 클러스터링할 수 있습니다.

대부분의 경우 테이블에서 구체화된 뷰의 하위 세트를 클러스터링하면 테이블 자체를 클러스터링하는 것보다 비용이 더 효율적입니다. 기본 테이블의 데이터는 (거의) 구체화된 뷰를 통해서만 액세스되며 (거의) 기본 테이블을 통해 직접 액세스되지 않는 경우 기본 테이블을 클러스터링하면 이점이 추가되지 않고 비용이 증가합니다.

기본 테이블 및 구체화된 뷰 모두를 클러스터링하려는 경우에는 Snowflake는 처음에는 구체화된 뷰만 클러스터링한 후 기본 테이블에 클러스터링을 추가하여 전후의 성능과 비용을 모니터링할 것을 권장합니다.

테이블을 생성하고 로드한 후 테이블에 클러스터된 구체화된 뷰를 생성하려는 경우, Snowflake는 구체화된 뷰를 마지막에 생성(가능한 많은 데이터를 로드한 후)할 것을 권장합니다. 그러면 구체화된 뷰를 처음 로드할 때 구체화된 뷰의 클러스터링을 유지하기 위한 추가적인 노력을 수행할 필요가 없으므로 초기 데이터 로드 비용을 절약할 수 있습니다.

클러스터링에 대한 자세한 내용은 다음을 참조하십시오.

구체화된 뷰 클러스터링 비용에 대한 자세한 내용은 다음을 참조하십시오.

구체화된 뷰와 Time Travel

현재, Time Travel 을 사용하여 구체화된 뷰에 대한 과거 데이터를 쿼리 할 수 없습니다.

하지만 다음 사항에 유의해야 합니다.

구체화된 뷰의 모범 사례

다음 섹션에는 구체화된 뷰 작업에 대한 모범 사례가 요약되어 있습니다.

구체화된 뷰 생성 모범 사례

  • 대부분의 구체화된 뷰에서는 다음 중 하나 또는 모두를 수행해야 합니다.

    • 데이터 필터링. 이 작업은 다음을 통해 수행할 수 있습니다.

      • 행 필터링(예: 가장 최근의 데이터만 포함되도록 구체화된 뷰 정의). 일부 애플리케이션의 경우 저장하기에 가장 적합한 데이터는 이상 데이터입니다. 예를 들어, 가스 파이프라인의 압력을 모니터링하여 파이프에서의 장애 발생 시점을 예측하는 경우 모든 압력 데이터를 기본 테이블에 저장하고 비정상적으로 높은 압력 측정값만 구체화된 뷰에 저장할 수 있습니다. 유사하게, 네트워크 트래픽을 모니터링하는 경우 모든 모니터링 정보를 기본 테이블에 저장하고 의심스러운 비정상 정보(예: DOS(서비스 거부) 공격을 시작하는 것으로 알려진 IP 주소)만 구체화된 뷰에 저장할 수 있습니다.

      • 열 필터링(예: 《SELECT * …》가 아닌 특정 열 선택). SELECT * ... 를 사용하여 구체화된 뷰를 정의하는 것은 일반적으로 비용이 많이 듭니다. 또한 오류가 발생할 수 있으며, 나중에 기본 테이블에 열이 추가되는 경우(예: ALTER TABLE ... ADD COLUMN ...) 구체화된 뷰는 새 열을 자동으로 통합하지 않습니다.

    • 리소스 집약적인 작업을 수행하고 결과를 저장하여 리소스 집약적인 작업을 자주 수행하지 않아도 되도록 합니다.

  • 동일한 기본 테이블에 대해 2개 이상의 구체화된 뷰를 생성할 수 있습니다. 예를 들어, 가장 최근 데이터만 포함된 구체화된 뷰 1개 및 비정상적인 데이터를 저장하는 다른 구체화된 뷰 1개를 생성할 수 있습니다. 그러면 두 테이블을 조인하고 과거의 비정상 데이터와 일치하는 최근 데이터를 표시하는 구체화되지 않은 뷰를 생성하여 증가하는 DOS(서비스 거부) 공격과 같은 이상 상황을 신속하게 감지할 수 있습니다.

    Snowflake는 다음에 해당하는 경우에만 비정상적인 데이터에 대한 구체화된 뷰를 사용하는 것을 권장합니다.

    • 기본 테이블이 클러스터링되지 않았거나 비정상적인 데이터를 포함하는 열이 기본 테이블의 클러스터링 키의 일부가 아닌 경우.

    • 데이터가 비정상이어서 쉽게 구분할 수 있지만, 거의 사용하지 않을 정도로 비정상적이지는 않은 경우. (데이터를 거의 사용하지 않는 경우에는 구체화된 뷰의 유지 관리 비용이 데이터 사용 시의 신속한 액세스를 통한 성능 이점 및 비용 절감 효과를 초과할 수 있습니다.)

구체화된 뷰 유지 관리 모범 사례

  • Snowflake는 기본 테이블에서 DML 연산을 일괄 처리하는 것을 권장합니다.

    • DELETE: 테이블이 가장 최근 기간(예: 가장 최근 날짜, 주 또는 월)에 해당하는 데이터를 저장하는 경우 이전 데이터를 삭제하여 기본 테이블을 자르면 기본 테이블에 대한 변경 사항이 구체화된 뷰로 전파됩니다. 마이크로 파티션에 데이터가 배포되는 방식에 따라 구체화된 뷰의 백그라운드 업데이트에서 더 많은 비용이 발생할 수 있습니다. 일부 경우에는 삭제 빈도를 줄여(예: 1시간마다가 아닌 매일 또는 10분마다가 아닌 1시간마다) 비용을 절약할 수 있습니다.

      특정한 수량의 오래된 데이터를 유지할 필요가 없는 경우에는 실험을 통해 비용과 기능 사이에서 최상의 균형을 찾아야 합니다.

    • INSERT, UPDATEMERGE: 기본 테이블에서 이러한 타입의 DML 문을 일괄 처리하면 구체화된 뷰의 유지 관리 비용을 절약할 수 있습니다.

구체화된 뷰 및 기본 테이블 클러스터링 모범 사례

  • 기본 테이블에 구체화된 뷰를 생성하는 경우 및 구체화된 뷰에 자주 액세스하고 기본 테이블에 자주 액세스하지 않는 경우에는 일반적으로 기본 테이블을 클러스터링하지 않는 것이 더 효율적입니다.

    기본 테이블의 클러스터링을 변경하면 구체화된 뷰를 새로 고쳐야 하므로 구체화된 뷰의 유지 관리 비용이 증가하기 때문에, 클러스터링된 테이블에 구체화된 뷰를 생성하는 경우에는 기본 테이블의 클러스터링을 제거하는 것이 좋습니다.

  • 구체화된 뷰, 특히 자주 변경되는 기본 테이블의 구체화된 뷰를 클러스터링하면 비용이 증가합니다. 필요 이상으로 구체화된 뷰를 클러스터링하지 마십시오.

  • 테이블 클러스터링에 대한 거의 모든 내용은 구체화된 뷰 클러스터링에도 적용됩니다. 테이블 클러스터링에 대한 자세한 내용은 클러스터링 키 선택 전략 를 참조하십시오.

이 섹션에는 구체화된 뷰 생성 및 사용에 대한 자세한 예를 제공합니다. 소개를 위한 단순 예는 이 항목의 기본 예: 구체화된 뷰 만들기 를 참조하십시오.

단순한 구체화된 뷰

이 첫 번째 예에서는 단순한 구체화된 뷰와 뷰에 대한 간단한 쿼리를 보여줍니다.

테이블 만들어 데이터 로드하기 및 뷰 만들기:

CREATE TABLE inventory (product_ID INTEGER, wholesale_price FLOAT,
  description VARCHAR);
    
CREATE OR REPLACE MATERIALIZED VIEW mv1 AS
  SELECT product_ID, wholesale_price FROM inventory;

INSERT INTO inventory (product_ID, wholesale_price, description) VALUES 
    (1, 1.00, 'cog');
Copy

뷰에서 데이터를 선택합니다.

SELECT product_ID, wholesale_price FROM mv1;
+------------+-----------------+
| PRODUCT_ID | WHOLESALE_PRICE |
|------------+-----------------|
|          1 |               1 |
+------------+-----------------+
Copy

구체화된 뷰 조인하기

테이블 또는 다른 뷰와 함께 구체화된 뷰를 조인할 수 있습니다. 이 예에서는 추가 테이블을 생성하고 구체화된 뷰를 테이블에 조인하는 이점을 표시하는 구체화되지 않은 뷰를 생성하여 앞에서 제공된 예시를 기반으로 합니다.

CREATE TABLE sales (product_ID INTEGER, quantity INTEGER, price FLOAT);

INSERT INTO sales (product_ID, quantity, price) VALUES 
   (1,  1, 1.99);

CREATE or replace VIEW profits AS
  SELECT m.product_ID, SUM(IFNULL(s.quantity, 0)) AS quantity,
      SUM(IFNULL(quantity * (s.price - m.wholesale_price), 0)) AS profit
    FROM mv1 AS m LEFT OUTER JOIN sales AS s ON s.product_ID = m.product_ID
    GROUP BY m.product_ID;
Copy

뷰에서 데이터를 선택합니다.

SELECT * FROM profits;
+------------+----------+--------+
| PRODUCT_ID | QUANTITY | PROFIT |
|------------+----------+--------|
|          1 |        1 |   0.99 |
+------------+----------+--------+
Copy

구체화된 뷰에 대한 업데이트 일시 중단

다음 예는 mv1 구체화된 뷰의 사용(및 유지 관리)을 일시적으로 중단하고 구체화된 뷰가 일시 중단된 동안 해당 뷰에 대한 쿼리에서 오류 메시지를 생성됨을 보여줍니다.

ALTER MATERIALIZED VIEW mv1 SUSPEND;
    
INSERT INTO inventory (product_ID, wholesale_price, description) VALUES 
    (2, 2.00, 'sprocket');

INSERT INTO sales (product_ID, quantity, price) VALUES 
   (2, 10, 2.99),
   (2,  1, 2.99);
Copy

구체화된 뷰에서 데이터를 선택합니다.

SELECT * FROM profits ORDER BY product_ID;
Copy

출력:

002037 (42601): SQL compilation error:
Failure during expansion of view 'PROFITS': SQL compilation error:
Failure during expansion of view 'MV1': SQL compilation error: Materialized View MV1 is invalid.
Copy

재개:

ALTER MATERIALIZED VIEW mv1 RESUME;
Copy

구체화된 뷰에서 데이터를 선택합니다.

SELECT * FROM profits ORDER BY product_ID;
+------------+----------+--------+
| PRODUCT_ID | QUANTITY | PROFIT |
|------------+----------+--------|
|          1 |        1 |   0.99 |
|          2 |       11 |  10.89 |
+------------+----------+--------+
Copy

구체화된 뷰 클러스터링

이 예에서는 구체화된 뷰를 생성한 후 클러스터링을 수행합니다.

이 문에서는 파이프라인(예: 천연 가스용)의 세그먼트에 대한 정보를 추적하는 테이블 2개를 생성합니다.

머지 않아 장애가 발생할 가능성이 가장 높은 세그먼트는 가장 오래된 세그먼트이거나 쉽게 부식되는 재료로 제작되거나 비정상적으로 높은 압력이 발생한 세그먼트이므로, 이 예에서는 각 파이프의 수명, 압력 및 재료(철, 구리, PVC 플라스틱 등)를 추적합니다.

CREATE TABLE pipeline_segments (
    segment_ID BIGINT,
    material VARCHAR, -- e.g. copper, cast iron, PVC.
    installation_year DATE,  -- older pipes are more likely to be corroded.
    rated_pressure FLOAT  -- maximum recommended pressure at installation time.
    );
    
INSERT INTO pipeline_segments 
    (segment_ID, material, installation_year, rated_pressure)
  VALUES
    (1, 'PVC', '1994-01-01'::DATE, 60),
    (2, 'cast iron', '1950-01-01'::DATE, 120)
    ;

CREATE TABLE pipeline_pressures (
    segment_ID BIGINT,
    pressure_psi FLOAT,  -- pressure in Pounds per Square Inch
    measurement_timestamp TIMESTAMP
    );
INSERT INTO pipeline_pressures 
   (segment_ID, pressure_psi, measurement_timestamp) 
  VALUES
    (2, 10, '2018-09-01 00:01:00'),
    (2, 95, '2018-09-01 00:02:00')
    ;
Copy

파이프라인 세그먼트는 자주 변경되지 않으며 가장 오래된 파이프라인 세그먼트에서 장애가 발생할 가능성이 가장 높은 세그먼트이므로 가장 오래된 세그먼트의 구체화된 뷰를 생성합니다.

CREATE MATERIALIZED VIEW vulnerable_pipes 
  (segment_ID, installation_year, rated_pressure) 
  AS
    SELECT segment_ID, installation_year, rated_pressure
        FROM pipeline_segments 
        WHERE material = 'cast iron' AND installation_year < '1980'::DATE;
Copy

클러스터링을 추가하거나 클러스터링 키를 변경할 수 있습니다. 예를 들어, installation_year 에서 클러스터링하려면:

ALTER MATERIALIZED VIEW vulnerable_pipes CLUSTER BY (installation_year);
Copy

새로운 압력 측정값은 자주(10초마다) 수신되므로 압력 측정값에 대한 구체화된 뷰의 유지 관리를 위해서는 많은 비용이 소요됩니다. 그러므로 최근 압력 데이터를 위해 높은 성능(빠른 검색)이 중요한 경우에도 pipeline_pressures 테이블은 구체화된 뷰를 사용하지 않고 시작됩니다.

성능이 너무 느린 경우에는 최근 압력 데이터만 포함하거나 이상 고압 이벤트에 대한 데이터만 포함된 구체화된 뷰를 생성할 수 있습니다.

구체화된 뷰와 pipeline_pressures 테이블의 정보를 결합하는 (구체화되지 않은) 뷰를 생성합니다.

CREATE VIEW high_risk AS
    SELECT seg.segment_ID, installation_year, measurement_timestamp::DATE AS measurement_date, 
         DATEDIFF('YEAR', installation_year::DATE, measurement_timestamp::DATE) AS age, 
         rated_pressure - age AS safe_pressure, pressure_psi AS actual_pressure
       FROM vulnerable_pipes AS seg INNER JOIN pipeline_pressures AS psi 
           ON psi.segment_ID = seg.segment_ID
       WHERE pressure_psi > safe_pressure
       ;
Copy

이제 고위험 파이프라인 세그먼트를 나열합니다.

SELECT * FROM high_risk;
+------------+-------------------+------------------+-----+---------------+-----------------+
| SEGMENT_ID | INSTALLATION_YEAR | MEASUREMENT_DATE | AGE | SAFE_PRESSURE | ACTUAL_PRESSURE |
|------------+-------------------+------------------+-----+---------------+-----------------|
|          2 | 1950-01-01        | 2018-09-01       |  68 |            52 |              95 |
+------------+-------------------+------------------+-----+---------------+-----------------+
Copy

여기서는 부식성 소재로 제작된 segment_id = 2 가 포함된 파이프라인 세그먼트가 오래되었음을 보여줍니다. 이 세그먼트는 설치 당시 최대 정격 압력보다 높은 압력이 발생한 적이 없지만, 시간이 지남에 따라 부식 가능성으로 인해 《안전 한계》가 감소하며, 발생한 최고 압력은 압력 측정 당시의 파이프만큼 오래된 파이프에 권장되는 압력을 초과합니다.

공유 데이터에 대한 구체화된 뷰 만들기

공유 데이터에 대한 구체화된 뷰를 생성할 수 있습니다.

계정1:

create or replace table db1.schema1.table1(c1 int);
create or replace share sh1;
grant usage on database db1 to share sh1;
alter share sh1 add accounts = account2;
grant usage on schema db1.schema1 to share sh1;
grant select on table db1.schema1.table1 to share sh1;
Copy

계정2:

create or replace database dbshared from share account1.sh1;
create or replace materialized view mv1 as select * from dbshared.schema1.table1 where c1 >= 50;
Copy

참고

구체화된 뷰의 유지 관리에는 크레딧이 소요됨을 기억해야 합니다. 다른 사용자의 공유 테이블에 구체화된 뷰를 생성할 때 해당 공유 테이블이 변경되면 구체화된 뷰에 대한 유지 관리가 수행되므로 비용이 발생합니다.

구체화된 뷰 공유하기

Snowflake의 데이터 공유 기능을 사용하여 구체화된 뷰를 공유할 수 있습니다.

데이터 공유에 대한 자세한 내용은 Snowflake의 데이터 공유 개요 를 참조하십시오.

참고

구체화된 뷰의 유지 관리에는 크레딧이 소요됨을 기억해야 합니다. 다른 사용자가 공유 데이터에 대한 구체화된 뷰를 생성하는 경우 공유 데이터가 변경되면 공유 데이터에 대한 구체화된 뷰를 보유한 사용자에게 요금이 부과될 수 있습니다. 공유 기본 테이블에 대한 구체화된 뷰 수가 많을수록 해당 기본 테이블을 효율적으로 업데이트하여 구체화된 뷰의 유지 관리 비용을 최소화하는 것이 중요합니다.

문제 해결

컴파일 오류: Failure during expansion of view '<이름>': SQL compilation error: Materialized View <이름> is invalid.

가능한 원인
  • 구체화된 뷰가 일시 중단되었습니다. 뷰 일시 중단 및 재개에 대한 자세한 내용은 ALTER MATERIALIZED VIEW 섹션을 참조하십시오.

  • 구체화된 뷰의 기본 테이블에 대한 변경으로 인해 구체화된 뷰가 무효화되었습니다. 예를 들어, 이 오류는 다음과 같은 경우에 반환됩니다.

    • 기본 테이블이 삭제된 경우.

    • 기본 테이블 열에서 한 열이 삭제되었습니다.

  • 백그라운드 프로세스에서 특정 유형의 오류(예: 《0으로 나누기》 오류)가 발생하여 구체화된 뷰를 새로 고치지 못했습니다.

가능한 해결책
  • 뷰가 일시 중단된 경우:

    • ALTER MATERIALIZED VIEW … RESUME 을 실행하여 뷰를 재개해 보십시오.

    • 기본 테이블에 대한 쿼리를 실행해 보십시오. 하지만 이럴 경우 구체화된 뷰에 대해 쿼리를 실행하는 것보다 크레딧을 더 많이 소비하고 시간도 더 오래 걸릴 수 있습니다.

  • 기본 테이블이 수정되거나 삭제된 경우:

    • 기본 테이블이 삭제된 경우에는 구체화된 뷰를 삭제합니다.

    • 기본 테이블이 수정하고(예: 뷰에서 참조한 열 삭제) 구체화된 뷰가 새 버전의 테이블에서 계속 유용할 경우에는 기본 테이블에 남은 열을 사용하여 구체화된 뷰를 삭제하고 다시 만들어 보십시오.

    • 이 오류 메시지가 나타날 다른 분명한 원인이 없으면 구체화된 뷰를 삭제하고 다시 만들어 보십시오.

    • 기본 테이블에 대한 쿼리를 실행해 보십시오. 하지만 이럴 경우 구체화된 뷰에 대해 쿼리를 실행하는 것보다 크레딧을 더 많이 소비하고 시간도 더 오래 걸릴 수 있습니다.

  • 오류로 인해 백그라운드 프로세스가 구체화된 뷰를 새로 고치지 못한 경우 오류 메시지에는 구체화된 뷰가 무효화된 이유에 대한 세부 정보가 포함되어야 합니다. 예:

    Failure during expansion of view 'MY_MV':
      SQL compilation error: Materialized View MY_MV is invalid.
      Invalidation reason: Division by zero
    

이 경우 오류 메시지에 설명된 문제를 해결하고 ALTER MATERIALIZED VIEW … RESUME 명령을 사용하여 구체화된 뷰를 재개합니다.

SHOW MATERIALIZED VIEWS 명령으로 업데이트되지 않은 구체화된 뷰 표시하기

가능한 원인

한 가지 가능한 원인은 뷰 정의에서 SELECT 문이 실패하여 새로 고치지 못했기 때문입니다.

새로 고침은 백그라운드 프로세스를 통해 수행되므로 새로 고침을 시도할 때 오류 메시지가 표시되지 않습니다. 대신 구체화된 뷰를 쿼리하거나 SHOW MATERIALIZED VIEWS 를 실행할 때 오류 메시지가 표시됩니다.

가능한 해결책

invalid 열이 true 인 경우 뷰가 무효화된 이유를 invalid_reason 열에서 확인하십시오.

일부 경우, 구체화된 뷰의 정의에서 SELECT 문을 수동으로 실행하거나 구체화된 뷰의 정의에서 참조하는 테이블에서 보다 단순한(비용이 적게 소비되는) SELECT 문을 실행하여 문제를 디버깅할 수 있습니다.

구체화된 뷰의 정확한 정의를 모르는 경우에는 SHOW MATERIALIZED VIEWS 의 출력이나 GET_DDL 함수를 사용하여 찾을 수 있습니다.