⛷️

SnowPro Core資格への道 ~Part5:マテリアライズドビュー(MATERIALIZED VIEW)

に公開

はじめに

9月のSnowflake World Tour TokyoまでにSnowPro Coreをとります!
試験を8月28日(木)に受けようと思います。

今日のお題はマテリアライズドビュー(MATERIALIZED VIEW)です。

マテリアライズドビューとは?

https://docs.snowflake.com/ja/user-guide/views-materialized
クエリの結果を事前に計算して物理的に保存しておくデータベースオブジェクトのことです。
通常のビューとは異なり、データがディスクに実際に格納されるため、複雑な集計や結合を含むクエリの実行時に、その都度計算し直す必要がなく、高速に結果を返すことができます。

「物理的」にデータを保存するっていうのと、「Enterprise Edition以上」で使用可能という2点は覚えておいた方が良さそうです。

ビューとマテリアライズドビューの違い

特徴 マテリアライズドビュー (MATERIALIZED VIEW) 通常のビュー (VIEW) セキュアビュー (SECURE VIEW)
データの保存 物理的に保存される 物理的に保存しない(仮想的) 物理的に保存しない(仮想的)
クエリパフォーマンス 非常に高速(事前計算済み) 実行時に毎回計算されるため、低速になる場合がある 通常のビューと同等か、わずかに遅くなる可能性あり (最適化情報が制限されるため)
データの鮮度 ほぼリアルタイム(自動更新に依存) 常に最新 常に最新
Snowflake クエリ最適化 クエリ書き換えにより、ベーステーブルへのクエリも高速化可能 なし(定義通りに実行) クエリ書き換えは行われない (ビュー定義が隠蔽されるため)
Snowflake コスト クエリ実行時 + 自動更新時にウェアハウス利用料発生
データストレージ料も発生
クエリ実行時のみウェアハウス利用料発生 クエリ実行時のみウェアハウス利用料発生 (通常のビューと同等)
主な用途 高速な分析、ダッシュボード、レポーティング クエリの簡素化、論理モデル 機密性の高いデータの保護、ビジネスロジックの隠蔽
管理の複雑さ 中程度(コストとデータ鮮度バランスの考慮) 低い 低い(セキュリティ要件による)
主な差別化ポイント パフォーマンス改善 - セキュリティと情報隠蔽

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

https://docs.snowflake.com/en/user-guide/views-materialized#materialized-views-cost

試してみた

ビューとマテリアライズドビューで物理的にどこのストレージに入るか試してみたくて下記SQLを動かしてみました。

-- ▼ 環境の準備(既存であればスキップ可)
CREATE DATABASE IF NOT EXISTS MY_VIEW_DEMO_DB;
CREATE SCHEMA IF NOT EXISTS MY_VIEW_DEMO_DB.VIEWS_SCHEMA;

USE DATABASE MY_VIEW_DEMO_DB;
USE SCHEMA VIEWS_SCHEMA;

---

-- ▼ 1. 元のテーブルの作成とデータ投入
CREATE TABLE MY_BASE_TABLE (
    ID INT,
    NAME VARCHAR(50),
    VALUE INT,
    CREATED_AT TIMESTAMP_NTZ
);

INSERT INTO MY_BASE_TABLE VALUES
(1, 'Alpha', 100, CURRENT_TIMESTAMP()),
(2, 'Beta', 200, CURRENT_TIMESTAMP()),
(3, 'Gamma', 150, CURRENT_TIMESTAMP());

---

-- ▼ 2. Standard View の作成
CREATE OR REPLACE VIEW MY_STANDARD_VIEW AS
SELECT
    ID,
    NAME,
    VALUE
FROM
    MY_BASE_TABLE
WHERE
    VALUE > 100;

---

-- ▼ 3. マテリアライズドビュー (Materialized View) の作成
CREATE OR REPLACE MATERIALIZED VIEW MY_MATERIALIZED_VIEW AS
SELECT
    NAME,
    SUM(VALUE) AS TOTAL_VALUE
FROM
    MY_BASE_TABLE
GROUP BY
    NAME;

---

-- ▼ 4. 各オブジェクトのストレージ使用量確認

-- 元のテーブルのストレージ使用量を確認
-- (物理的にデータが保存されているため、バイト数が表示されます)
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    ACTIVE_BYTES / (1024*1024) AS ACTIVE_BYTES_MB -- アクティブなデータのバイト数をMBに変換
FROM
    SNOWFLAKE.ACCOUNT_USAGE.TABLE_STORAGE_METRICS
WHERE
    TABLE_SCHEMA = 'VIEWS_SCHEMA' AND TABLE_NAME = 'MY_BASE_TABLE'
ORDER BY
    TABLE_NAME;

---

-- Standard View のストレージ使用量を確認
-- (データは物理的に保存されないため、通常0バイトが表示されます)
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    ACTIVE_BYTES / (1024*1024) AS ACTIVE_BYTES_MB
FROM
    SNOWFLAKE.ACCOUNT_USAGE.TABLE_STORAGE_METRICS
WHERE
    TABLE_SCHEMA = 'VIEWS_SCHEMA' AND TABLE_NAME = 'MY_STANDARD_VIEW'
ORDER BY
    TABLE_NAME;

---

-- マテリアライズドビューのストレージ使用量を確認
-- (物理的にデータが保存されているため、バイト数が表示されます)
SELECT
    TABLE_SCHEMA,
    TABLE_NAME,
    ACTIVE_BYTES / (1024*1024) AS ACTIVE_BYTES_MB
FROM
    SNOWFLAKE.ACCOUNT_USAGE.TABLE_STORAGE_METRICS
WHERE
    TABLE_SCHEMA = 'VIEWS_SCHEMA' AND TABLE_NAME = 'MY_MATERIALIZED_VIEW'
ORDER BY
    TABLE_NAME;

SNOWFLAKE.ACCOUNT_USAGE.TABLE_STORAGE_METRICSが出てこないー。
そうだった、SNOWFLAKE.ACCOUNT_USAGEはリアルタイムで表示されない!(1‐2時間後に反映)っということで少し寝かせてから更新します(7/4 17時頃)。

ビューを作成してから4時間後(7/4 21時)にストレージを確認

4番以降を実行してみました。
ビューの取得元テーブルはこのように0.001953

スタンダードビューはレコードなし

マテリアライズドビューは0.001465

まとめ

マテリアライズドビューは物理的にデータが保存されることによってスピードが上がる
という公式ドキュメントの説明が、このSQLを動かして納得できました。
あらかじめマテリアライズドビューで集計したデータを物理的に保存しているからこそ、集計結果が速く出てくるという流れなんだなという理解が深まりました。

Discussion