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

マテリアライズドビューは、クエリ仕様(ビュー定義の SELECT )から派生した事前に計算されたデータセットであり、後で使用するために保存されます。データは事前に計算されているため、マテリアライズドビューのクエリは、元のクエリを実行するよりも高速です。このパフォーマンスの違いは、クエリが頻繁に実行される場合、または非常に複雑な場合に顕著になります。

注釈

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

このトピックの内容:

マテリアライズドビューを使用する場合

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

  • クエリ結果には、ベーステーブル(ビューが定義されているテーブル)に相対的な少数の行や列が含まれます。

  • クエリ結果には、次のような重要な処理が必要な結果が含まれます:

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

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

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

  • ビューのベーステーブルは頻繁に変更されません。

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

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

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

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

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

重要

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

マテリアライズドビューと通常のビュー

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

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

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

    • ビューの結果は頻繁に使用されます(通常、クエリ結果が変更されるよりもかなり頻繁に使用されます)。

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

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

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

    • 結果は頻繁に使用されません(結果が変更される割合と比較して)。

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

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

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

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

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

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

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

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

  • クエリセキュリティ。

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

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

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

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

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

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

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

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

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

パフォーマンスの利点

セキュリティ上の利点

クエリロジックを簡素化

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

ストレージを使用

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

注意

通常のテーブル

通常表示

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

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

マテリアライズドビュー

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

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

このセクションでは、マテリアライズドビューの作成と使用に関する情報を提供します。

マテリアライズドビュー DDL および DML

マテリアライズドビューは、ファーストクラスのデータベースオブジェクトです。Snowflakeには、マテリアライズドビューを作成および管理するための次の DDL コマンドが用意されています:

Snowflakeは、マテリアライズドビューで標準の DML (例: INSERT、 UPDATE、 DELETE)を許可しません。Snowflakeでは、ユーザーがマテリアライズドビューを切り捨てることはできません。

標準コマンドを使用して、マテリアライズドビューの権限の付与および取り消しができます。

マテリアライズドビューの権限の詳細については、 アクセス制御権限 (このトピック)をご参照ください。

一般的な使用シナリオ

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

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

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

    • 残りの時間、 Q を実行すると、テーブルに保存された S のサブクエリの結果が参照されます。

    これは、サブクエリ S の結果が予想どおりに変化する限りうまく機能します(例えば、毎週同じ時間に)。

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

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

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

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

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

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

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

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

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

一般的な使用上の注意

  • 可能な場合はいつでも、マテリアライズドビューで参照されるベーステーブルの完全修飾名を使用してください。これにより、ベーステーブルをビューから別のスキーマに移動する(またはその逆)など、ビューを無効にする可能性のある変更からビューが隔離されます。

    ベーステーブルの名前が修飾されておらず、テーブルまたはビューが別のスキーマに移動された場合、参照は無効になります。

  • マテリアライズドビューが最初に作成されると、Snowflakeは CTAS (CREATE TABLE ... AS ....)と同等の操作を実行します。これは、 CREATE MATERIALIZED VIEW ステートメントの完了にかなりの時間がかかる可能性があることを意味します。

  • マテリアライズドビューのメンテナンスはバックグラウンドプロセスによって実行され、ユーザーがタイミングを予測することはできません。メンテナンスが遅れると、ビューが最新の場合よりもクエリの実行が遅くなる可能性があります。ただし、結果は常に正しいものになります。マテリアライズドビューの一部のマイクロパーティションが古い場合、Snowflakeはそれらのパーティションをスキップし、ベーステーブルのデータを検索します。

  • ビューのメンテナンスを中断する場合、メンテナンスを再開するまでビューをクエリしないでください。

  • SHOW VIEWS コマンドは、マテリアライズドビューと通常ビューの両方に関する情報を返します。

  • INFORMATION_SCHEMA.TABLES はマテリアライズドビューを表示します。 TABLE_TYPE 列には「MATERIALIZED VIEW」が表示されます。マテリアライズドビューに直接挿入できないため、 IS_INSERTABLE 列は常に「NO」です。

  • INFORMATION_SCHEMA.VIEWS はマテリアライズドビューを表示しません。マテリアライズドビューは INFORMATION_SCHEMA.TABLESで表示されます。

  • マテリアライズドビューが最後に更新された時間を確認するには、コマンド SHOW MATERIALIZED VIEWS の出力の REFRESHED_ON 列と BEHIND_BY 列を確認します。

マテリアライズドビューの保護

マテリアライズドビューは安全なビューにすることができます。

セキュアビューに関するほとんどの情報は、セキュアマテリアライズドビューに適用されます。安全なマテリアライズドビューが安全な非マテリアライズドビューと異なる場合がいくつかあります。違いは次のとおりです:

  • ビューが安全かどうかを確認するコマンド。

    • 非マテリアライズドビューの場合は、 SHOW VIEWS コマンドの出力の IS_SECURE 列を確認してください。

    • マテリアライズドビューの場合は、 SHOW MATERIALIZED VIEWS コマンドの出力の IS_SECURE 列を確認してください。

安全なビューの詳細については、 安全なビューの使用 をご参照ください。

安全なマテリアライズドビューを作成するための構文は、 CREATE MATERIALIZED VIEW に文書化されています。

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

注釈

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

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

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

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

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

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

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

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

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

    • UDFs

    • ウィンドウ関数。

    • HAVING 句。

    • ORDER BY 句。

    • LIMIT 句。

    • SELECT リスト内にないGROUP BY キー。マテリアライズドビューの GROUP BY キーはすべて、 SELECT リストの一部である必要があります。

    • GROUP BY GROUPING SETS

    • GROUP BY ROLLUP

    • GROUP BY CUBE

    • マテリアライズドビュー内のサブクエリのネスト。

  • 多くの集計関数は、マテリアライズドビューの定義では許可されていません。

    注釈

    マテリアライズドビューで許可される集計関数には、まだいくつかの制限があります:

    • 集計関数はネストできません。

    • 複雑な式(例: (sum(salary)/10))で使用される集計関数は、クエリの最も外側のレベルでのみ使用でき、サブクエリやインラインビューでは使用できません。

      たとえば、次は許可されています。

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

      以下は許可 emph:されていません

      create materialized view mv2 as
          select
              y + 10
            from (
              select
                sum(x) as y
              from t
            );
      
    • DISTINCT は集約関数と組み合わせることはできません。

    • マテリアライズドビューでは、集計関数 AVGCOUNTMINMAX および SUM を集計関数として使用できますが、ウィンドウ関数としては使用できません。マテリアライズドビューでは、これらの関数は OVER 句と共に使用できません。

      OVER ( [ PARTITION BY <expr1> ] [ ORDER BY <expr2> ] )
      
    • 集計関数がサブクエリ内にある場合、マテリアライズドビューは、そのサブクエリの集計列の上に式を作成できません。例えば、次のマテリアライズドビューの定義を考えます。

      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);
      

      式「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);
      
  • マテリアライズドビューで使用される関数は決定的でなければなりません。たとえば、 CURRENT_TIME または CURRENT_TIMESTAMP の使用は許可されていません。

  • マテリアライズドビューは、セッションレベルのパラメーター TIMESTAMP_TYPE_MAPPING など、パラメーターの設定ごとに異なる結果を生成する関数を使用して定義しないでください。

    たとえば、ビューが次のように定義されているとします。

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

    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;
    

    これは、 マテリアライズド ビューに特有の問題です。非マテリアライズドビューは、現在のパラメーター設定に基づいて動的に出力を生成するため、結果が古くなることはありません。

  • Snowflakeの「Time Travel」機能は、マテリアライズドビューではサポートされていません。

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

注釈

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

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

  • マテリアライズドビューが定義されているベーステーブルと一貫性を保つために、マテリアライズドビュー自体でほとんどの DML 操作を実行できません。例えば、マテリアライズドビューに行を直接挿入することはできません(もちろん、ベーステーブルには行を挿入できます)。禁止されている DML 操作は次のとおりです:

    • COPY

    • DELETE

    • INSERT

    • MERGE

    • UPDATE

    マテリアライズドビューの切り捨てはサポートされていません。

  • CREATE VIEW ... CLONE... コマンドを使用して、マテリアライズドビューを直接クローンすることはできません。ただし、マテリアライズドビューを含むスキーマまたはデータベースを複製すると、マテリアライズドビューが複製され、新しいスキーマまたはデータベースに含まれます。

  • 現在、マテリアライズドビューではTime Travelはサポートされていません。

  • マテリアライズドビューはSnowflake リソースモニターの操作 によって監視されません。

ベーステーブルの変更

Snowflakeでは、ベーステーブルへの変更は、そのテーブルに基づいてマテリアライズドビューに自動的に伝播されません。

  • ベーステーブルに列が追加された場合、それらの新しい列はマテリアライズドビューに自動的に反映されません。これは、マテリアライズドビューが SELECT * (例: CREATE MATERIALIZED VIEW AS SELECT * FROM table2 ... )で定義されていた場合でも同様です。マテリアライズドビューの列は、マテリアライズドビューが定義されたときに定義されます。マテリアライズドビューがクエリされるたびに SELECT * は動的に解釈されません。混乱を避けるために、Snowflakeは、マテリアライズドビューの定義で SELECT * を使用しないことをお勧めします。

  • 既存の列が変更または削除されるようにベーステーブルが変更された場合、そのベーステーブルのすべてのマテリアライズドビューが中断されます。マテリアライズドビューは使用または維持できません。(これは、変更または削除された列がマテリアライズドビューの一部ではない場合でも当てはまります。)そのマテリアライズドビューは RESUME できません。再度使用する場合は、再作成する必要があります。ドロップして新しいビューを作成し、 GRANT および REVOKE コマンドを実行してビューの権限を再作成できますが、ビューを再作成する最も効率的な方法は通常、 CREATE OR REPLACE VIEW <ビュー名> ... COPY GRANTS ... 実行してビューを単一のコマンドに置き換えることです。

  • ALTER TABLE ... ADD <列> は、そのベーステーブルで作成されたマテリアライズドビューを中断しません。

  • ベーステーブルがドロップされると、マテリアライズドビューは中断されます(ただし、自動的にはドロップされません)。ほとんどの場合で、マテリアライズドビューをドロップする必要があります。何らかの理由でベーステーブルを再作成し、以前と同じ定義でマテリアライズドビューを再作成したい場合は、最初にベーステーブルを再作成し、次に CREATE OR REPLACE VIEW <ビュー名> ... COPY GRANTS ... を使用してビューを置き換えます。

マテリアライズドビューと、スキーマまたはデータベースの複製

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

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

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

異なるユーザーが異なる方法でビューを「調整」したい場合、マテリアライズドビューのみをクローンすると便利です。たとえば、元のビューをクラスター化たものとは異なる列で複製されたビューをクラスター化できます。

基本的な例:マテリアライズドビューの作成

このセクションには、マテリアライズドビューの作成と使用の基本的な例が含まれています。

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

SELECT * FROM mv1;

より詳細な例は、(このトピック)の にあります。

アクセス制御権限

マテリアライズドビューに関連する3種類の権限があります。

  • マテリアライズドビューを含むスキーマに対する権限。

  • マテリアライズドビュー自体に対する直接の権限。

  • マテリアライズドビューがアクセスするデータベースオブジェクト(例:テーブル)の権限。

マテリアライズドビューのスキーマに対する権限

マテリアライズドビューはストレージスペースを消費します。マテリアライズドビューを作成するには、マテリアライズドビューを含むスキーマに対する CREATE MATERIALIZED VIEW 権限が必要です。次のようなステートメントを実行する必要があります。

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

GRANT ステートメントの詳細については、 GRANT <権限> ... TO ROLE をご参照ください。

マテリアライズドビューの権限

マテリアライズドビューは、他のデータベースオブジェクト(テーブル、ビュー、 UDFsなど)と同様に、ロールによって所有され、他のロールに付与できる権限を持っています。

マテリアライズドビューで次の権限を付与できます:

  • SELECT

非マテリアライズドビューと同様に、マテリアライズドビューはそのベーステーブルの権限を自動的に継承しません。マテリアライズドビューの権限を、そのビューを使用するロールに明示的に付与する必要があります。

マテリアライズドビューによってアクセスされるデータベースオブジェクトの権限

非マテリアライズドビューの場合と同様に、マテリアライズドビューにアクセスするユーザーは、ビューが参照する基になるオブジェクトではなく、ビューに対する権限のみが必要です。

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

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

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

  • コンピューティングリソース:マテリアライズドビューが古くなるのを防ぐために、Snowflakeはマテリアライズドビューの自動バックグラウンドメンテナンスを実行します。ベーステーブルが変更されると、テーブルで定義されているすべてのマテリアライズドビューは、Snowflakeが提供する計算リソースを使用するバックグラウンドサービスによって更新されます。

    これらの更新はかなりのリソースを消費する可能性があり、その結果、クレジットの使用状況が増加します。ただし、Snowflakeは、実際に使用されたリソースに対してのみアカウントに請求することにより、効率的なクレジット使用状況を保証します。請求は1秒単位で計算されます。

コストの見積もりと管理

マテリアライズドビューを維持するためのコストを見積もるツールはありません。一般的に、コストは次の要素に比例します:

  • 各ベーステーブルで作成されるマテリアライズドビューの数、およびベーステーブルが変更されたときに各マテリアライズドビューで変更されるデータの量。ベーステーブルのマイクロパーティションを変更すると、再クラスタリングによるものか、ベーステーブルでの DML ステートメントの実行によるものかに関わらず、最終的なマテリアライズドビューのメンテナンスが必要になります。

  • クラスタ化されているマテリアライズドビューの数。(テーブルまたはマテリアライズドビューの)クラスタリングを維持すると、コストが増加します。

    マテリアライズドビューがベーステーブルとは異なる方法でクラスタ化されている場合、マテリアライズドビューで変更されたマイクロパーティションの数は、ベーステーブルで変更されたマイクロパーティションの数よりも大幅に多くなる可能性があります。

    たとえば、ベーステーブルがデータの挿入(追加)によって大幅に変更され、クラスタ化されていないため、ベーステーブルは主に行がテーブルに挿入された順序になっているとします。マテリアライズドビューが、郵便番号などの独立した列によってクラスタ化されていると想像してください。100個の新しい行がベーステーブルに追加されると、それらは1つまたは2つの新しいマイクロパーティションに入れられ、ベーステーブル内の他のマイクロパーティションはそのまま残ります。ただし、これらの100行では、クラスタ化されたマテリアライズドビューの100マイクロパーティションを書き換える必要がある場合があります。

    別の例として、削除を検討してください。クラスタ化されていないベーステーブルの最も古い行を削除すると、最も古いマイクロパーティションのみが削除される可能性がありますが、マテリアライズドビューで、年齢によってクラスタ化されていないはるかに多数のマイクロパーティションへの変更が必要になる場合があります。

    (マテリアライズドビューのクラスタリングの詳細については、 マテリアライズドビューとクラスタリング をご参照ください。)

作成するビューの数、作成するテーブル、および各ビューの定義(そのビューの行と列の数を含む)を慎重に選択することにより、マテリアライズドビューの維持コストを制御できます。

また、マテリアライズドビューを一時停止または再開することにより、コストを制御できます。ただし、メンテナンスの一時停止は通常、コストを削減するのではなく、延期するだけです。メンテナンスが延期されているほど、より多くのメンテナンスを行う必要があります。

マテリアライズドビューを維持するためのベストプラクティス もご参照ください。

ちなみに

マテリアライズドビューを維持するコストが心配な場合、Snowflakeはこの機能をゆっくりと開始し(つまり、選択したテーブルにいくつかのマテリアライズドビューのみを作成すること)長期にわたりコストを監視することをお勧めします。

コストの表示

マテリアライズドビューを維持するための請求費用は、ウェブインターフェイスまたは SQLを使用して表示できます:

ウェブインターフェイス

アカウント管理者として、 Account Account tab » Billing & Usage をクリックします。

クレジットコストは、Snowflakeが提供する Snowflake logo in blue (no text) MATERIALIZED_VIEW_MAINTENANCE という名前の仮想ウェアハウスで追跡されます。

SQL

次のいずれかをクエリします。

例:

SELECT * FROM TABLE(INFORMATION_SCHEMA.MATERIALIZED_VIEW_REFRESH_HISTORY());

注釈

リソースモニター は、仮想ウェアハウスのクレジット使用状況を制御します。ただし、これらを使用して、 Snowflake logo in blue (no text) MATERIALIZED_VIEW_MAINTENANCE ウェアハウスを含む、Snowflake提供のウェアハウスのクレジット使用状況を制御することはできません。

マテリアライズドビューとクラスタリング

マテリアライズドビューでのクラスタリングキーの定義がサポートされており、多くの状況でパフォーマンスを向上させることができます。ただし、コストもかかります。

マテリアライズドビューとマテリアライズドビューが定義されているベーステーブルの両方をクラスタ化する場合、ベーステーブルのクラスタ化に使用される列とは異なる列でマテリアライズドビューをクラスタ化できます。

ほとんどの場合、テーブル上のマテリアライズドビューのサブセットをクラスタリングする方が、テーブル自体をクラスタリングするよりも費用効果が高い傾向があります。ベーステーブルのデータがマテリアライズドビューを通じてのみ(ほとんど)アクセスされ、(ほとんど)ベーステーブルから直接アクセスされない場合、ベーステーブルをクラスタリングすると、利益を追加せずにコストが追加されます。

ベーステーブルとマテリアライズドビューの両方をクラスタリングすることを検討している場合、Snowflakeは、マテリアライズドビューのみをクラスタリングすることから始め、ベーステーブルにクラスタリングを追加する前後にパフォーマンスとコストを監視することをお勧めします。

テーブルを作成してロードし、テーブルにクラスタ化されたマテリアライズドビューを作成する場合、Snowflakeは、マテリアライズドビューを最後に作成することをお勧めします(できるだけ多くのデータをロードした後)。これにより、マテリアライズドビューが初めてロードされるときにマテリアライズドビューのクラスタリングを維持するための余分な労力が回避されるため、初期データロードの費用を節約できます。

クラスタリングの詳細については、 Snowflakeテーブル構造について および 自動クラスタリング をご参照ください。

マテリアライズドビューのクラスタリングのコストの詳細については、 マテリアライズドビューのメンテナンスコストマテリアライズドビューのベストプラクティス をご参照ください。

マテリアライズドビューのベストプラクティス

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

  • ほとんどのマテリアライズドビューは、次のいずれかまたは両方を実行する必要があります:

    • データをフィルタリングします。これを実行するには:

      • 行をフィルタリングします(例:非常に最近のデータのみが含まれるようにマテリアライズドビューを定義)。一部のアプリケーションでは、保存に最適なデータは異常なデータです。たとえば、ガスパイプラインの圧力をモニターしてパイプの故障の可能性を推定する場合、すべての圧力データをベーステーブルに保存し、マテリアライズドビューには異常に高い圧力測定値のみを保存します。同様に、ネットワークトラフィックをモニターしている場合、ベーステーブルにはすべてのモニター情報が保存される可能性がありますが、マテリアライズドビューには、異常で疑わしい情報(例: 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');

ビューからデータを選択します:

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

マテリアライズドビューへの参加

マテリアライズドビューをテーブルまたは別のビューに結合できます。この例は、追加のテーブルを作成し、次にマテリアライズドビューをテーブルに結合することで利益を表示する非マテリアライズドビューを作成することにより、前の例に基づいています:

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;

ビューからデータを選択します:

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

マテリアライズドビューへの更新の一時停止

次の例は、 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);

マテリアライズドビューからデータを選択します:

SELECT * FROM profits ORDER BY product_ID;

出力:

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.

レジュメ:

ALTER MATERIALIZED VIEW mv1 RESUME;

マテリアライズドビューからデータを選択します:

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

マテリアライズドビューのクラスタリング

この例では、マテリアライズドビューを作成し、後でクラスタ化します。

これらのステートメントは、パイプラインのセグメントに関する情報を追跡する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')
    ;

パイプラインセグメントはあまり頻繁に変更されず、最も古いパイプラインセグメントが最も故障する可能性が高いセグメントであるため、最も古いセグメントのマテリアライズドビューを作成します。

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;

クラスタリングを追加したり、クラスタリングキーを変更したりできます。例えば、 installation_year でクラスタリングするには:

ALTER MATERIALIZED VIEW vulnerable_pipes CLUSTER BY (installation_year);

新しい圧力測定値は頻繁に(おそらく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
       ;

次に、リスクの高いパイプラインセグメントをリストします:

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 |
+------------+-------------------+------------------+-----+---------------+-----------------+

これは、腐食する材料でできている 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;

アカウント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;

注釈

マテリアライズドビューを維持するとクレジットが消費されることに注意してください。他の誰かの共有テーブルにマテリアライズドビューを作成する場合、その共有テーブルに変更を加えると、マテリアライズドビューが維持されるため料金が発生します。

マテリアライズドビューの共有

Snowflakeのデータ共有機能を使用して、マテリアライズドビューを共有できます。

データ共有の詳細については、 Snowflakeでのデータの安全な共有 をご参照ください。

注釈

マテリアライズドビューを維持するとクレジットが消費されることに注意してください。他の誰かが共有データのマテリアライズドビューを作成する場合、共有データに変更を加えると、共有データのマテリアライズドビューを持っている人に料金が発生する可能性があります。共有ベーステーブルのマテリアライズドビューの数が多いほど、そのベーステーブルを効率的に更新して、マテリアライズドビューを維持するコストを最小限に抑えることが重要になります。

トラブルシューティング

コンパイルエラー: Failure during expansion of view '<名前>': SQL compilation error: Materialized View <名前> is invalid.

原因

多くの場合、これはマテリアライズドビューの基になっている基になるテーブルの変更が原因です。例えば、テーブルが削除された場合、またはマテリアライズドビューがテーブル列を参照しているが、列が削除された場合、このエラーが返されます。

解決策

テーブルが削除されていて、再作成されない場合は、おそらくビューを削除する必要があります。

テーブルが変更されているが、まだ存在する場合、残っている列を使用して、マテリアライズドビューを削除および再作成できる場合があります。

SHOW MATERIALIZED VIEWS コマンドは更新されないマテリアライズドビューを表示します

原因

考えられる原因の1つは、ビュー定義の SELECT が失敗したために更新が失敗したことです。

更新中に SELECT が失敗すると、更新は失敗します。ただし、更新はバックグラウンドで行われるため、更新の試行時にエラーメッセージは表示されません。

マテリアライズドビューのデータの一部またはすべてが古い場合、Snowflakeはベーステーブルから最新のデータを取得します。Snowflakeは、マテリアライズドビューが更新されなかったというエラーメッセージを発行しません。

したがって、リフレッシュも後続のクエリも、ビューの SELECT が失敗したことを必ずしも示しません。更新が失敗しているかどうかを検出するには、コマンド SHOW MATERIALIZED VIEWS を使用して、 refreshed_on という名前の列を探します。データが更新されない場合、 SELECT が失敗している可能性があります。

解決策

基になるテーブルが存在することを確認してください。ビューが定義されているテーブルをドロップしても、ビューをドロップしない場合、ビューは存在し続けます。

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

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