目次
はじめに
これまでのSnowflakeでのデータパイプライン構築のためには、タスク、ストリームなどの複数のオブジェクトを作成する必要がありました。複数のオブジェクトがあると煩雑になり、また、オブジェクト管理をそれぞれに対して行う必要があります。
これらオブジェクトをひとまとめにしてデータパイプライン構築を簡便にする方法としてDynamic Tableが2024/04/29に一般公開となりました。タスク、ストリームを使用するデータパイプライン構築に煩雑さを感じていた著者としては、ぜひこのDynamic Tableを使ってみたいと思い、今回調査してみました。
Dynamic Tableとは
動的テーブル | Snowflake Documentation
Dynamic Tableは、指定したクエリの結果を具体化します。データ取得元テーブルが更新されれば、それを検知してDynamic Tableのデータも更新されます。
DDLの例は以下です。以下の例のDYNAMIC_TBL_CUSTOMERSは、一分ごとにCUSTOMERSテーブルの更新を確認し、CUSTOMERSテーブルが更新されていれば、データの更新を行います。
CREATE OR REPLACE DYNAMIC TABLE DYNAMIC_TBL_CUSTOMERS
TARGET_LAG = '1 minutes'
WAREHOUSE = DYNAMIC_TBL_WH
AS
SELECT *
FROM CUSTOMERS
;
マテリアライズドビューとの違い
上記の説明をみると取得元テーブルが更新されると更新するマテリアライズドビューとの違いがわかりづらいですが、大きな違いとしては、マテリアライズドビューでは単一のテーブルからデータを取得するのに対し、Dynamic Tableでは複数のテーブルからデータを取得することが可能です。
マテリアライズドビューとの違いについての詳細は、以下のリンク参照。
ストリーム、タスク、およびマテリアライズドビューと比較した動的テーブル | Snowflake Documentation
Dynamic Tableの制約
Dynamic Tableで下記を使用するとエラーになります。
- 外部関数
- 非決定性関数(動的テーブルでサポートされる非決定性関数 にリストされているものを除く)
- 外部テーブル、ストリーム、およびマテリアライズドビューを含むソース
- 動的テーブルやその他のサポートされていないオブジェクトのビュー
動的テーブルの作成 | Snowflake Documentation
Dynamic Tableデータリフレッシュの方法
データのリフレッシュの方法として、「増分リフレッシュ」と「フルリフレッシュ」があります。
- 「増分リフレッシュ」は、データ取得元テーブルのデータ変更部分を用いてマージによりDynamic Tableを更新します。
- 「フルリフレッシュ」は、Dynamic Tableで指定したクエリ結果が全件更新されます。
- 指定したクエリが「増分リフレッシュ」を適用できる場合は「増分リフレッシュ」になりますが、適用できない場合は「フルリフレッシュ」になります。
- CREATE DYNAMIC TABLE内のオプションパラメーター「REFRESH_MODE」で「増分リフレッシュ」と「フルリフレッシュ」を指定することができますが、「増分リフレッシュ」適用できない場合は「増分リフレッシュ」を指定できません。
- 「増分リフレッシュ」、「フルリフレッシュ」どちらが適用されているかは、後述するSnowsightでのモニタリングの画面で確認できます。
- 「フルリフレッシュ」になる場合の例としては、「FROM 句外のサブクエリ」があります(著者の確認範囲では「UNION」もフルリフレッシュになりそうです)。
- 詳しくは、以下のリンク参照
動的テーブルリフレッシュについて | Snowflake Documentation
使用調査結果
Dynamic Tableによるデータパイプライン作成
前述のとおりCREATE DYNAMIC TABLEだけです(簡単!)。
動的テーブルの作成 | Snowflake Documentation
モニタリング&操作
Snowsightでモニタリング&操作することができます。
下図はリフレッシュの履歴です。更新時間、更新行数が確認できます。
上図のGraghタブを選択すると下図のようにDynamic Tableを構成するDAGが表示されます。
- Dynamic Tableの更新停止・起動や手動Refreshができます(ALTER DYNAMIC TABLE <name> SUSPEND; ALTER DYNAMIC TABLE <name> REFRESH; でも操作可能です)。
- Refreshモードには、更新パターン(フルリフレッシュ「Full」か増分リフレッシュ「Incremental」)が表示されます。
下図のように、クエリでもリフレッシュ履歴を確認できます。
- REFRESH_ACTIONカラムには、データ取得元テーブルの更新がなかったことを表す「NO_DATA」、データ取得元テーブルの更新されたことを表す「FULL」や「INCREMENTAL」が入ります。
コスト
動的テーブルのコストについて | Snowflake Documentation
仮想ウェアハウスのコンピューティング: 動的テーブルには、ベースオブジェクトが最初に事前設定されるときや、後ほど継続的にリフレッシュされるときに、ベースオブジェクトに対してクエリを実行するための仮想ウェアハウスが必要です。
ちょっと確認してみました。
更新のないテーブルを取得元とするDynamic Table(TARGET_LAGは1分)をInformation Schemaのテーブル関数warehouse_metering_historyで確認したところ、テーブル作成時にウェアハウスを使用しましたが、その後は、クラウドサービスのクレジットを消費していました(注:2023/10時点調査)。
クラウドサービス使用時のコストは以下のようになっています。
クラウドサービスのコンピューティングコストには、日次クラウドサービスコストがアカウントの日次ウェアハウスコストの10%より大きい場合にのみ、Snowflakeによって請求されるという制約が適用されます。
更新が稀なDynamic Tableではクラウドサービスのコストがかかる可能性も出てくるため、取得元テーブルの個数やテーブルデータの大きさごとにクラウドサービスのコストについて調査してみました。その結果、取得元テーブルの個数、テーブルの行数、列数を変化させても、クラウドサービスのクレジットに大きな変化ありませんでした(TARGET_LAG1分を1時間起動で0.004クレジット程度)。
気になるのは更新の際のクレジットということ、調査しました。
結論としては、ウェアハウス利用のためのクレジットは、通常のクエリと同様にDDLで指定したウェアハウスのサイズと時間に依存します。(ドキュメントのどこにも追加料金かかるとは書かれていないので、あたり前かもしれません。)
↓の画像は、XSのウェアハウスを指定して1分以内で終わる更新を1回実行した結果です(注:2023/10時点調査)。「credits_used_compute」カラムが使われたクレジットです。
2024/05時点では、サーバーレスタスクのような実行時間きっちりで課金されるようには指定はできないので、1回の更新では最低でも1分間分の料金が発生するようです。
参考:ウェアハウス、実行時間ごとのクレジット
実行時間 | クレジット (XS) | クレジット (XL) | クレジット (5XL) |
---|---|---|---|
0~60秒間 | 0.017 | 0.267 | 4.268 |
61秒間 | 0.017 | 0.271 | 4.336 |
2分間 | 0.033 | 0.533 | 8.532 |
10分間 | 0.167 | 2.667 | 42.668 |
1時間 | 1.000 | 16.000 | 256.000 |
※サーバーレスタスクのクレジットは「Snowflakeサービス利用テーブル」参照。
おわりに
Dynamic Tableについて調査しました。
Dynamic Tableを使うメリットとしては以下が考えられます。
- マテビューではできない複数のテーブルからのデータ取得が可能
- タスク、プロシージャ、ストリーム、テーブルのオブジェクトをまとめられる
- Snowsightによりモニタリングや操作(起動・停止・手動リフレッシュ)がしやすい
Dynamic Table用のSnowsightの機能が充実しているため、今後も機能追加や性能向上が期待されます!