マテリアライズドビューの使用

マテリアライズドビューは、クエリ仕様(ビュー定義の SELECT )から派生した事前に計算されたデータセットであり、後で使用するために保存されます。データは事前に計算されているため、マテリアライズドビューのクエリは、ビューのベーステーブルに対してクエリを実行するよりも高速です。このパフォーマンスの違いは、クエリが頻繁に実行される場合、または非常に複雑な場合に顕著になります。その結果、マテリアライズドビューは、特に頻繁に実行され、大規模なデータセットで実行される、高価な集計、射影、および選択操作を高速化できます。

注釈

マテリアライズドビューは、一般的な繰り返しのクエリパターンで構成される、ワークロードのクエリパフォーマンスを向上させるように設計されています。ただし、中間結果を具体化すると、 追加コスト が発生します。そのため、マテリアライズドビューを作成する前に、これらの結果を十分頻繁に再利用して得られる節約分が、コストを相殺できるかどうかを検討する必要があります。

マテリアライズドビューを作成するタイミングの決定

マテリアライズドビューは、次の場合に特に役立ちます:

  • クエリ結果に、ベーステーブル(ビューが定義されているテーブル)と比較して少数の行や列が含まれる。

  • クエリ結果に、次のような著しい処理が必要な結果が含まれる。

    • 半構造化データの分析。

    • 計算に時間がかかる集計。

  • クエリが外部テーブル(つまり、外部ステージのファイルに格納されているデータセット)上にあるため、ネイティブデータベーステーブルのクエリに比べてパフォーマンスが低下する可能性がある。

  • ビューのベーステーブルは頻繁に更新されない。

マテリアライズドビューの利点

マテリアライズドビューのSnowflakeの実装は、多くのユニークな特性を提供します。

  • マテリアライズドビューは、同じサブクエリの結果を繰り返し使用するクエリのパフォーマンスを向上させることができます。

  • マテリアライズドビューは、Snowflakeによって自動的かつ透過的に維持されます。バックグラウンドサービスは、ベーステーブルに変更が加えられた後、マテリアライズドビューを更新します。これは、アプリケーションレベルでマテリアライズドビューに相当するものを手動で維持するよりも効率的で、エラーが発生しにくくなります。

  • ベーステーブルで実行された DML の量に関係なく、マテリアライズドビューを介してアクセスされるデータは常に最新です。マテリアライズドビューが最新になる前にクエリが実行されると、Snowflakeはマテリアライズドビューを更新するか、マテリアライズドビューの最新部分を使用して、必要な新しいデータをベーステーブルから取得します。

重要

マテリアライズドビューの自動メンテナンスはクレジットを消費します。詳細については、 マテリアライズドビューのコスト (このトピック内)をご参照ください。

マテリアライズドビューまたは通常のビューを作成するタイミングの決定

一般に、マテリアライズドビューと通常のビューのどちらを作成するかを決定するときは、次の基準を使用します。

  • 次の すべて に当てはまる場合は、マテリアライズドビューを作成します。

    • ビューからのクエリ結果は頻繁に変更されない。これは、ほとんどの場合、ビューの基になる/ベーステーブルが頻繁に変更されないこと、または少なくともマテリアライズドビューで使用されるベーステーブル行のサブセットが頻繁に変更されないことを意味します。

    • ビューの結果が頻繁に使用される(通常、クエリ結果の変更の頻度よりも大幅に多い)。

    • クエリは多くのリソースを消費します。通常、これはクエリが多くの処理時間またはクレジットを消費することを意味しますが、クエリが中間結果のために多くのストレージスペースを消費することも意味します。

  • 次の いずれか が当てはまる場合は、通常のビューを作成します。

    • ビューの結果は頻繁に変更される。

    • 結果の使用頻度が低い(結果の変更の割合と比較して)。

    • クエリはリソースを集中的に使用しないため、再実行するのにコストはかかりません。

これらの基準は単なるガイドラインです。マテリアライズドビューにより、頻繁に使用されない場合でも、特に結果がビューの使用よりも頻繁に変更されない場合でも、利点を得られる可能性があります。

また、通常のビューを使用するかマテリアライズドビューを使用するかを決定する際に考慮すべき他の要因があります。

たとえば、マテリアライズドビューを格納するコストは要因の1つです。結果があまり頻繁に使用されない場合(変更よりも頻繁に使用されたとしても)、追加のストレージコストがパフォーマンスの向上に見合わない可能性があります。

テーブル、通常のビュー、キャッシュされた結果との比較

マテリアライズドビューは、いくつかの点でテーブルに似ており、他の点では通常の(つまり非マテリアライズド)ビューに似ています。さらに、マテリアライズドビューにはキャッシュされた結果といくつかの類似点があります。特に、両方とも将来の再利用のためにクエリ結果を保存できるためです。

このセクションでは、以下を含む、特定の領域におけるこれらのオブジェクトの類似点と相違点について説明します:

  • クエリのパフォーマンス。

  • クエリのセキュリティ。

  • クエリのロジックの複雑性軽減。

  • データクラスタリング(クエリパフォーマンスに関連)。

  • ストレージとメンテナンスのコスト。

Snowflakeは、クエリの実行後、短時間クエリ結果をキャッシュします。状況によっては、同じクエリが再実行され、クエリがアクセスするテーブルに何も変更がなければ、Snowflakeはクエリを再実行せずに同じ結果を単に返すことができます。これは最速かつ最も効率的な再利用の形式ですが、柔軟性が最も低くなります。詳細については、 保存済みのクエリ結果の使用 をご参照ください。

マテリアライズドビューとキャッシュされたクエリ結果の両方により、クエリのパフォーマンスが向上します:

  • マテリアライズドビューは、キャッシュされた結果よりも柔軟性がありますが、一般的には低速です。

  • マテリアライズドビューは、「キャッシュ」(つまり、ビューのクエリ結果)のためにテーブルよりも高速です。さらに、データが変更された場合、変更されていないデータには「キャッシュ」を使用し、変更されたデータにはベーステーブルを使用できます。

通常のビューはデータをキャッシュしないため、キャッシュによってパフォーマンスを向上させることはできません。ただし、場合によっては、ビューはSnowflakeがより効率的なクエリプランを生成するのに役立ちます。また、マテリアライズドビューと通常のビューの両方で、行レベルまたは列レベルでデータを公開または非表示にできるため、データセキュリティが強化されます。

次の表に、テーブル、通常のビュー、キャッシュされたクエリ結果、およびマテリアライズドビューの主な類似点と相違点を示します:

パフォーマンス上の利点

セキュリティ上の利点

クエリロジックを簡素化

クラスタリングをサポート

ストレージを使用

メンテナンスにクレジットを使用

メモ

通常のテーブル

通常のビュー

キャッシュされたクエリ結果

データが変更されておらず、クエリが決定論的関数のみを使用する場合(例: CURRENT_DATE ではない)にのみ使用されます。

マテリアライズドビュー

通常、ストレージとメンテナンスの要件により、 コストが増加 します。

外部テーブル

データはSnowflakeの外部で維持されるため、Snowflake内でのストレージ料金は発生しません。

マテリアライズドビューの使用例

このセクションでは、マテリアライズドビューの概念的な概要も提供する、一般的な使用シナリオをいくつか説明します。

  • 毎日、サブクエリ S を含むクエリ Q を実行するとします。 S がリソースを集中的に使用し、週に1回しか変更されないデータをクエリする場合、 S を実行し、結果を CT という名前のテーブルにキャッシュすることで、外部クエリ Q のパフォーマンスを改善できます:

    • テーブルは週に一度だけ更新します。

    • 残りの時間では、 Q を実行すると、テーブルに格納されている S のサブクエリ結果が参照されます。

    これは、サブクエリ S の結果が予測どおりに変化する限り(例: 毎週同時刻)、正しく機能します。

    ただし、 S の結果が予期せず変更される場合、結果をテーブルにキャッシュすることは危険です。サブクエリ S の結果が古い場合(したがって、キャッシュテーブル CT の結果が古い場合)、メインクエリ Q が古い結果を返すことがあります。

    理想的には、まれにしか変更されないが、変更のタイミングが予測できない結果のための特別なタイプのキャッシュが必要です。別の見方をすると、必要に応じてサブクエリ S を強制的に再実行(およびキャッシュテーブル CT を更新)したいと考えています。

    マテリアライズドビューは、両方の長所の近似を実装します。マテリアライズドビューのクエリを定義すると、クエリの結果は(内部テーブルに格納されているように)キャッシュされますが、Snowflakeは、マテリアライズドビューを定義するテーブルが更新されるとキャッシュを更新します。したがって、サブクエリの結果は、高速パフォーマンスのためにすぐに利用できます。

  • それほど抽象的ではない例として、大規模な薬局の小さな支店を経営しており、その支店が合計数万の FDA承認済みの医薬品の中から数百の医薬品を在庫しているとします。

    また、各顧客が服用するすべての医薬品の完全なリストがあり、それらの顧客のほとんどすべてが在庫のある医薬品のみを注文していると仮定します(つまり、特別注文はまれです)。

    このシナリオでは、在庫のある医薬品の相互作用のみをリストするマテリアライズドビューを作成できます。顧客がこれまでに使用したことのない医薬品を注文したときに、その医薬品と顧客が服用している他のすべての医薬品の両方がマテリアライズドビューでカバーされている場合は、 FDA データベース全体で薬物相互作用を確認する必要はありません。マテリアライズドビューの確認のみで済むため、検索が高速になります。

  • マテリアライズドビューを単独で使用することも、結合して使用することもできます。

    薬局の例を続けて、各顧客が服用するすべての薬をリストした1つのテーブルがあるとします。そのテーブルを薬物相互作用のマテリアライズドビューに結合して、顧客が現在服用している薬のどれが新しい薬と相互作用する可能性があるのかを調べることができます。

    マテリアライズドビューにあるかどうかに関係なく、外部結合を使用して、顧客の医薬品の すべて を確実にリストすることができます。外部結合により、現在の医薬品のいずれかがマテリアライズドビューにないことが示される場合は、包括的な薬物相互作用テーブルでクエリを再実行できます。

クエリオプティマイザーがマテリアライズドビューを使用する方法

ビューを使用するために、 SQL ステートメントでマテリアライズドビューを指定する必要はありません。クエリオプティマイザーは、ベーステーブルまたは通常のビューに対するクエリを自動的に書き換えて、代わりにマテリアライズドビューを使用します。

たとえば、マテリアライズドビューに、ベーステーブルに対するクエリで必要なすべての行と列が含まれているとします。オプティマイザーは、ベーステーブルではなくマテリアライズドビューを使用するように、クエリを書き換えることを決定できます。これにより、特にベーステーブルに大量の履歴データが含まれている場合、クエリを劇的に高速化できます。

別の例として、マルチテーブル結合の場合、オプティマイザーは、結合にあるテーブルの1つのために、テーブルではなくマテリアライズドビューの使用を決定する場合があります。

注釈

マテリアライズドビューが特定のクエリのベーステーブルを置き換えることができる場合でも、オプティマイザーは、マテリアライズドビューを使用しない場合があります。たとえば、ベーステーブルがフィールドによってクラスター化されていると、オプティマイザーは、パーティションを効率的にプルーニングし、ベーステーブルを使用して同等のパフォーマンスを提供できるため、ベーステーブル(マテリアライズドビューではない)のスキャンを選択する場合があります。

マテリアライズドビューは、サブクエリのデータソースとしても使用できます。

オプティマイザーが、マテリアライズドビューを暗黙的に使用することを選択した場合、マテリアライズドビューは、ベーステーブルではなく 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

    書き換えられたクエリは、column_2による追加のグループ化を活用しませんが、その追加のグループ化によってブロックされることもありません。

マテリアライズドビューの作成に関する制限

注釈

これらは現在の制限です。それらのいくつかは、将来のバージョンで削除または変更される可能性があります。

マテリアライズドビューの作成には、次の制限が適用されます。

  • マテリアライズドビューは単一のテーブルのみをクエリできます。

  • 自己結合を含む結合はサポートされていません。

  • マテリアライズドビューは次をクエリできません。

    • マテリアライズドビュー。

    • 非マテリアライズドビュー。

    • UDTF (ユーザー定義テーブル関数)。

  • マテリアライズドビューには以下を含めることはできません。

    • UDFs (この制限は、外部関数を含むすべてのタイプのユーザー定義関数に適用されます)。

    • ウィンドウ関数。

    • HAVING 句。

    • ORDERBY 句。

    • 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はそれらのパーティションをスキップし、ベーステーブルからのデータを検索します。

  • バックグラウンドプロセスで特定のユーザーエラーが発生した場合(例: ビューに対するクエリの結果が「ゼロ除算」エラーになった場合)、プロセスはマテリアライズドビューを無効にします。

    無効なマテリアライズドビューをクエリするとエラーになります。エラーメッセージには、マテリアライズドビューが無効になった理由が含まれます。例:

    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 コマンドを使用してマテリアライズドビューを再開します。

マテリアライズドビューのメンテナンスの中断および再開

マテリアライズドビューのメンテナンスと使用を中断する必要がある場合は、 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. ビューに対して同じ権限を作成する(GRANT および REVOKE)。

ベーステーブルの名前変更またはスワップ

ベーステーブル(またはベーステーブルを含むスキーマまたはデータベース)の名前を変更またはスワップすると、マテリアライズドビューは、マテリアライズドビューの作成に使用されたベーステーブルとは異なるベーステーブルを参照する可能性があります。これが発生する可能性がある状況の例を次に示します。

  • ベーステーブルの名前が変更され(ALTER TABLE ... RENAME を介して)、ベーステーブルの元の名前で別のテーブルが作成される。

  • マテリアライズドビューのベーステーブルが別のテーブルとスワップされる(ALTER TABLE ... SWAP WITH を介して)。

  • マテリアライズドビューのベーステーブルを含むスキーマまたはデータベースが、 DROP、 SWAP、または RENAME を介して移動される。

このような場合、マテリアライズドビューは中断されます。ほとんどの場合、ビューを使用するためにマテリアライズドビューを再作成する必要があります。

ベーステーブルのドロップ

ベーステーブルがドロップされると、マテリアライズドビューは中断されます(ただし、自動的にはドロップされません)。

ほとんどの場合で、マテリアライズドビューをドロップする必要があります。

何らかの理由でベーステーブルを再作成し、以前と同じ定義でマテリアライズドビューを再作成する場合は、最初にベーステーブルを再作成し、次に CREATE OR REPLACE MATERIALIZED VIEW <ビュー名> ... COPY GRANTS ... を使用してビューを置き換えます。

クローンされたスキーマとデータベースのマテリアライズドビュー

マテリアライズドビューが含まれたスキーマまたはデータベースをクローンすると、マテリアライズドビューがクローンされます。

マテリアライズドビューと対応するベーステーブルを(同一の CREATE SCHEMA ... CLONE または CREATE DATABASE ... CLONE 操作の一部として)同時にクローンする場合、クローンされたマテリアライズドビューは、クローンされたベーステーブルを参照します。

ベーステーブルをクローンせずにマテリアライズドビューをクローンする場合(例: テーブルがデータベース1.スキーマ1、ビューがデータベース1.スキーマ2にあり、データベース1すべてではなく、スキーマ2のみをクローン)、クローンビューは元のベーステーブルを参照します。

マテリアライズドビューのコスト

マテリアライズドビューは、ストレージリソースとコンピューティングリソースの両方のコストに影響します。

  • ストレージ: 各マテリアライズドビューにはクエリ結果が保存され、アカウントの月間ストレージ使用量が増加します。

  • コンピューティングリソース:マテリアライズドビューが古くなるのを防ぐために、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日平均

    このクエリは、マテリアライズドビューによって消費された日次の平均クレジットを、前年の週別にグループ化して表示します。1年間の日次平均の異常を特定するのに役立ちます。これにより、消費の急増や予期しない変化をさらに調査することができます。

    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 ...)、マテリアライズドビューには新しい列が自動的に組み込まれません。

    • リソースを集中的に使用する操作を実行し、結果を保存して、リソースを集中的に使用する操作を頻繁に実行する必要がないようにします。

  • 同じベーステーブルに対して複数のマテリアライズドビューを作成できます。たとえば、最新のデータのみを含む1つのマテリアライズドビューと、異常なデータを格納する別のマテリアライズドビューを作成できます。その後、2つのテーブルを結合し、異常な履歴データと一致する最近のデータを表示する非マテリアライズドビューを作成して、増加している DOS (サービス拒否)攻撃などの異常な状況をすばやく検出できます。

    Snowflakeは、次の場合にのみ、異常なデータのマテリアライズドビューをお勧めします。

    • ベーステーブルがクラスタ化されていないか、異常なデータを含む列がベーステーブルのクラスタリングキーの一部ではない場合。

    • データは簡単に分離できるほど異常ではあるものの、ほとんど使用されないほど異常ではない場合。(データがほとんど使用されない場合、使用時に迅速にアクセスできるため、マテリアライズドビューを維持するためのコストは、パフォーマンス上のメリットとコスト節約を上回る可能性があります。)

マテリアライズドビューを維持するためのベストプラクティス

  • Snowflakeは、ベーステーブルでDML操作をバッチ処理することをお勧めします。

    • DELETE: テーブルに最新の期間(例: 最新の日、週、月)のデータが格納されている場合は、古いデータを削除してベーステーブルをトリミングすると、ベーステーブルへの変更がマテリアライズドビューに反映されます。データがマイクロパーティション全体にどのように分散されているかによっては、マテリアライズドビューのバックグラウンド更新により多くの費用がかかる可能性があります。場合によっては、削除の頻度を減らすことでコストを削減できる場合があります(例えば、1時間ごとではなく1日ごと、または10分ごとではなく1時間ごと)。

      特定の量の古いデータを保持する必要がない場合は、コストと機能の最適なバランスを見つけるために実験する必要があります。

    • INSERTUPDATE、および MERGE :ベーステーブルでこれらのタイプの 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 をご参照ください。

  • マテリアライズドビューのベーステーブルの変更により、マテリアライズドビューが無効になった。たとえば、次の場合にこのエラーが返されます。

    • ベーステーブルがドロップされた。

    • ベーステーブル列の列が削除された。

  • バックグラウンドプロセスで特定の種類のエラー(例: 「ゼロ除算」エラー)が発生し、マテリアライズドビューのリフレッシュに失敗した。

考えられる解決策
  • ビューが中断されている場合、

    • 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 コマンドは更新されていないマテリアライズドビューを表示する

考えられる原因

考えられる原因の1つは、ビュー定義の SELECT ステートメントに失敗したため、リフレッシュに失敗したことです。

リフレッシュはバックグラウンドプロセスで実行されるため、リフレッシュ時にエラーメッセージが表示されることはありません。代わりに、マテリアライズドビューにクエリを実行したとき、または SHOW MATERIALIZED VIEWS を実行したときにエラーメッセージが表示されます。

考えられる解決策

invalid 列が true の場合は、 invalid_reason 列でビューが無効となった理由を確認します。

場合によっては、マテリアライズドビューの定義で SELECT ステートメントを手動で実行するか、マテリアライズドビューの定義で参照されるテーブルでより単純な(より安価な) SELECT ステートメントを実行することで、問題をデバッグできる場合があります。

マテリアライズドビューの正確な定義がわからない場合は、 SHOW MATERIALIZED VIEWS の出力で見つけるか、 GET_DDL 関数を使用して見つけることができます。