動的テーブルリフレッシュについて¶
動的テーブルのコンテンツは、特定のクエリの結果に基づいています。動的テーブルの基となるデータが変更されると、その変更を反映してテーブルが更新されます。これらの更新は リフレッシュ と呼ばれます。このプロセスは自動化されており、テーブルの基礎となるクエリを分析します。
動的テーブルリフレッシュのタイムアウトは STATEMENT_TIMEOUT_IN_SECONDS パラメーターによって決定され、アカウントまたはウェアハウスが自動的にキャンセルされるまでの最大期間を定義します。
以下のセクションでは、動的テーブルリフレッシュについて詳しく説明します。
動的テーブルのリフレッシュモード¶
動的テーブルリフレッシュプロセスは、次の2つの方法のいずれかで動作します。
増分リフレッシュ: この自動化されたプロセスでは、動的テーブルのクエリを分析し、前回のリフレッシュからの変更点を計算します。そして、これらの変更をテーブルにマージします。サポートされるクエリの詳細については、 増分リフレッシュでサポートされるクエリ をご参照ください。
フルリフレッシュ: 自動プロセスが増分リフレッシュを実行できない場合、フルリフレッシュを実行します。これには、動的テーブルのクエリを実行し、以前の具体化された結果を完全に置き換えることが含まれます。
クエリで使用されるコンストラクトは、増分リフレッシュが使用できるかどうかを決定します。動的テーブルを作成した後、 テーブルをモニター して、そのテーブルのリフレッシュに増分リフレッシュまたはフルリフレッシュが使用されているかどうかを判断することができます。
ターゲットラグについて¶
動的テーブルのリフレッシュは、データの古さの度合い、または ターゲットラグ と一般的に呼ばれるものに基づいてトリガーされます。動的テーブルのターゲットラグは、直接上流の動的テーブルではなく、グラフのルートのベーステーブルを基準として測定されます。Snowflakeは、動的テーブルの実際のラグをターゲットラグ以下に保つようにリフレッシュをスケジュールします。各リフレッシュの所要時間は、クエリ、データパターン、ウェアハウスサイズによって異なります。ターゲットラグを選択する際には、ルートへ チェーンの動的テーブル をそれぞれリフレッシュするのに必要な時間を考慮してください。そうしないと、一部のリフレッシュがスキップされ、実際のラグが大きくなる可能性があります。
動的テーブルに接続されているテーブルのグラフを見るには、 Snowsightを使用した動的テーブルグラフの調査 をご参照ください。
ターゲットラグは2つの方法のいずれかで指定します。
鮮度の測定: テーブルのコンテンツがベーステーブルの更新から遅れる最大時間を定義します。
次の例では、
product
動的テーブルを1時間ごとにリフレッシュし、鮮度を保つように設定しています。ALTER DYNAMIC TABLE product SET TARGET_LAG = '1 hour';下流:他の依存する動的テーブルがリフレッシュされる時に、その動的テーブルがオンデマンドでリフレッシュされるように指定します。このリフレッシュは、下流動的テーブルの手動またはスケジュールされたリフレッシュによってトリガーされます。
以下の例では、
product
は他の動的テーブルに基づいており、その下流動的テーブルのターゲットラグに基づいてリフレッシュするように設定されています。ALTER DYNAMIC TABLE product SET TARGET_LAG = DOWNSTREAM;
ターゲットラグは、動的テーブルのリフレッシュ頻度に反比例します。
動的テーブル1(DT1)に基づいて動的テーブル2(DT2)が定義されている場合を考えてみましょう。DT2は、 DT1 から読み取り、そのコンテンツを具体化する必要があります。さらに、レポートはクエリを介して DT2 データを消費します。

各動的テーブルがラグをどのように指定するかによって、次のような結果が考えられます。
動的テーブル1(DT1) |
動的テーブル2(DT2) |
リフレッシュの結果 |
---|---|---|
|
|
DT2 は最大10分ごとに更新されます。DT1は、ラグをDT2から推測 し、DT2が更新をリクエストするたびに更新されます。 |
|
|
このシナリオは避ける必要があります。レポートクエリはデータを受け取りません。DT1は頻繁にリフレッシュされ、DT2はリフレッシュされません。これは、DT2に基づく動的テーブルがないからです。 |
|
|
DT2は、最大5分前のDT1からのデータで約10分ごとに更新されます。 |
|
|
DT1 に定義されたラグを持つ下流の子がないため、 DT2 は定期的にはリフレッシュされません。 |
増分リフレッシュでサポートされるクエリ¶
次のテーブルでは、現在増分リフレッシュをサポートしている式、キーワード、句について説明します。増分リフレッシュをサポートしないクエリのリストについては、 増分リフレッシュのサポートの制限 をご参照ください。
キーワード/句 |
増分リフレッシュのサポート |
---|---|
WITH |
サブクエリで増分リフレッシュをサポートする機能を使用する 共通テーブル式(CTE)。 |
SELECT 内の式 |
|
FROM |
ソーステーブル、ビュー、およびその他の動的テーブル。FROM 句外のサブクエリ(例: WHERE EXISTS)はサポートされていません。 |
OVER |
すべての ウィンドウ関数。 |
WHERE/HAVING/QUALIFY |
SELECT で有効な式と同じ式のフィルター。 |
JOIN (およびテーブルを結合するための他の式) |
増分リフレッシュでサポートされる結合タイプには、内側結合、外部等価結合、クロス結合、および横方向のフラット化(静的でない FLATTEN テーブル関数のみ)があります。結合するテーブルはいくつでも指定でき、結合内にあるすべてのテーブルの更新はクエリの結果に反映されます。 側方フラット化結合からフラット化 SEQ 列を選択することは、増分リフレッシュではサポートされていません。 |
UNION ALL |
動的テーブルは、 UNION ALL をサポートします。 |
GROUP BY |
動的テーブルは、 GROUP BY をサポートします。 |
重要
クエリが増分リフレッシュに対応していない式を使用している場合、自動リフレッシュプロセスでは代わりにフルリフレッシュが使用され、追加のコストが発生する可能性があります。どのリフレッシュモードが使用されるかの判断については、 増分リフレッシュまたはフルリフレッシュのいずれが使用されているかの判断 をご参照ください。
増分リフレッシュを使用する動的テーブルで使用中の IMMUTABLE ユーザー定義関数(UDF)を置き換えると、そのテーブルで未定義の動作が発生します。VOLATILE UDFs は増分リフレッシュではサポートされていません。
現在、横方向の結合は増分リフレッシュではサポートされていません。ただし、リフレッシュモードを INCREMENTAL
に設定することで、 LATERAL を FLATTEN () と併用することができます。
例:
CREATE TABLE persons
AS
SELECT column1 AS id, parse_json(column2) AS entity
FROM values
(12712555,
'{ name: { first: "John", last: "Smith"},
contact: [
{ business:[
{ type: "phone", content:"555-1234" },
{ type: "email", content:"j.smith@company.com" } ] } ] }'),
(98127771,
'{ name: { first: "Jane", last: "Doe"},
contact: [
{ business:[
{ type: "phone", content:"555-1236" },
{ type: "email", content:"j.doe@company.com" } ] } ] }') v;
CREATE DYNAMIC TABLE example
TARGET_LAG = DOWNSTREAM
WAREHOUSE = mywh
REFRESH_MODE = INCREMENTAL
AS
SELECT p.id, f.value, f.path
FROM persons p,
LATERAL FLATTEN(input => p.entity) f;
注釈
側方フラット化結合からフラット化 SEQ 列を選択することは、増分リフレッシュではサポートされていません。
演算子が増分リフレッシュする方法¶
以下のテーブルは、各演算子がどのように増分化されるのか(つまり、完全な結果の代わりに変更を生成する新しいクエリフラグメントに変換されるのか)、そのパフォーマンスとその他の考慮すべき重要な要因の概要を示しています。
演算子 |
増分 |
考慮事項 |
---|---|---|
SELECT <スカラー式> |
変更された行に式を適用することで増分されます。 |
パフォーマンスは良好で、特に考慮すべき点はありません。 |
WHERE <スカラー式> |
変更された各行で述語を評価し、述語が真であるものだけを含めることによって増分されます。 |
パフォーマンスは通常良好です。コストは変更の大きさに応じて直線的に変化します。 非常に選択的なWHERE式で動的テーブルをリフレッシュすると、結果として動的テーブルが変更されなくても、ウェアハウスのアップタイムが必要になることがあります。これは、ソースのどの変更が述語を満たすかを判断するためにウェアハウスが必要になる場合があるためです。 |
FROM <ベーステーブル> |
前回のリフレッシュ以降にテーブルに追加または削除されたマイクロパーティションをスキャンすることで増分されます。 |
コストは、追加または削除されたマイクロパーティション内のデータ量に比例します。 推奨事項:
|
<クエリ> UNIONALL <クエリ> |
各サイドの変更をすべて統合して増分します。 |
パフォーマンスは良好で、特に考慮すべき点はありません。 |
WITH <CTEリスト> <クエリ> |
各共通表式の変更を計算することによって増分。 |
WITHは複雑なクエリを読みやすくしますが、1つの動的テーブルの定義を複雑にしすぎないように注意してください。詳細については、 動的テーブルのパイプラインのチェーン および 複雑な動的テーブルに対する増分リフレッシュモードのパフォーマンスの最適化 をご参照ください。 |
スカラー集計 |
スカラー集計は現在、効率的に増分されません。入力が変更されると、完全に再計算されます。 |
|
GROUPBY <キー> |
変更されたグループ化キーごとに集計を再計算することで増分されます。 |
ソースデータがクラスタリングキーによってクラスタ化され、変更点がグループ化キーのごく一部 (おおよそ<5%) であることを確認します。 グループ化キーがベース列ではなく複合式を含む場合、増分リフレッシュは大量のデータをスキャンしなければならないかもしれません。これらのスキャンのサイズを小さくするために、式を1つの動的テーブルで マテリアライズ し、次に別の動的テーブルでマテリアライズされた列にグループ化操作を適用します。 例えば、次のような複合ステートメントを考えてみましょう: CREATE DYNAMIC TABLE sums
AS
SELECT date_trunc(minute, ts), sum(c1) FROM table
GROUP BY 1;
上記のステートメントは次のように最適化できます: CREATE DYNAMIC TABLE intermediate
AS
SELECT date_trunc(minute, ts) ts_min, c1 FROM table;
CREATE DYNAMIC TABLE sums
AS
SELECT ts_min, sum(c1) FROM intermediate
GROUP BY 1;
|
DISTINCT |
GROUPBYALLに相当し、集計関数はありません。 |
多くの場合、実質的な最適化の機会を意味します。 誤って重複を発生させないためには、DISTINCTをクエリ全体に自由に適用するのが一般的な方法です。増分リフレッシュでは、DISTINCT操作がリフレッシュのたびに重複をチェックする必要があるため、定期的にリソースを消費します。 パフォーマンスを最適化する場合、冗長なDISTINCTsを見つけて削除するのは簡単なことです。これは、さらに上流で重複を排除し、結合のカーディナリティを注意深く検討することで実現します。 |
<fn> OVER <ウィンドウ> |
変更されたパーティションキーごとにウィンドウ関数を再計算することで増分されます。 |
クエリにPARTITIONBY句があり、ソースデータがパーティションキーでクラスタリングされていることを確認してください。また、変更がパーティションのごく一部(おおよそ<5%)であることを確認してください。 |
<左> INNERJOIN <右> |
左側の変更を右側と結合し、右側の変更を左側と結合することによって増分されます。 |
接合の片側が小さければ、パフォーマンスは良好となります。結合の片側が頻繁に変更される場合、結合キーでもう片側をクラスタリングするとパフォーマンスが向上する可能性があります。 |
<左> [{LEFT | RIGHT | FULL }] OUTER JOIN <右> |
1つまたは2つのNOTEXISTSでinner-join union-all-edにファクタリングすることで増分し、一致しない値に対してNULLsを計算します。このファクタリングされたクエリは増分されます。 内部結合は図のように増分されます。not-existsは、片側で変更されたキーがもう片側で既に存在していたかどうかをチェックすることで増分されます。 |
推奨事項:
|
フルリフレッシュでサポートされる非決定性関数¶
動的テーブルでは、以下の非決定性関数がサポートされています。これらの関数はフルリフレッシュでのみサポートされていることに注意してください。増分リフレッシュでサポートされない内容のリストについては、 増分リフレッシュのサポートに関する制限 をご参照ください。
動的テーブルが他の動的テーブルに依存している場合のデータのリフレッシュ方法¶
動的テーブルのラグが時間の尺度として指定されている場合、自動リフレッシュプロセスは、動的テーブルのターゲットラグタイムに基づいて、リフレッシュのスケジュールを決定します。このプロセスは、各テーブルのターゲットラグタイムに最適なスケジュールを選択します。
注釈
ターゲットラグは保証ではありません。代わりに、Snowflakeが達成を目指すターゲットです。動的テーブルのデータは、ターゲットラグの範囲内で可能な限りリフレッシュされます。しかし、ウェアハウスのサイズ、データサイズ、クエリの複雑さ、および類似の要因などのために、ターゲットラグを超える可能性があります。
ある動的テーブルが別の動的テーブルに依存 している場合にデータの一貫性を保つために、このプロセスはアカウント内のすべての動的テーブルを互換性のあるタイミングでリフレッシュします。リフレッシュの頻度が低いタイミングは、リフレッシュの頻度が高いタイミングと一致します。
たとえば、動的テーブルAのターゲットラグが2分で、ターゲットラグが1分の動的テーブルBをクエリするとします。このプロセスでは、Aは96秒ごと、Bは48秒ごとにリフレッシュする必要があると判断される可能性があります。その結果、このプロセスは以下のスケジュールを適用する可能性があります。
特定の時点 |
リフレッシュされる動的テーブル |
---|---|
2022-12-01 00:00:00 |
A, B |
2022-12-01 00:00:48 |
B |
2022-12-01 00:01:36 |
A, B |
2022-12-01 00:02:24 |
B |
つまり、互いに依存する一連の動的テーブルをクエリするときは、いつでも、これらのテーブルにまたがるデータの同じ「スナップショット」をクエリしていることになります。
動的テーブルのターゲットラグは、それが依存する動的テーブルのターゲットラグよりも短くはできないことに注意してください。たとえば、次の場合を考慮します。
動的テーブルAが動的テーブルBとCをクエリします。
動的テーブルBのターゲットラグは5分です。
動的テーブルCのターゲットラグは1分です。
つまり、Aのターゲットラグタイムは5分より短くすることはできません(つまり、BとCのラグタイムの長い方より短くすることはできません)。
Aのラグを5分に設定した場合、プロセスは以下の目標があるリフレッシュスケジュールを設定します。
ラグが1分以下になるよう、Cを頻繁にリフレッシュします。
AとBを一緒にリフレッシュし、ラグが5分以下になるように十分な頻度でリフレッシュします。
スナップショットの分離を確実にするために、AとBのリフレッシュがCのリフレッシュと一致するようにします。
注: リフレッシュに時間がかかりすぎる場合、スケジューラーはリフレッシュをスキップして最新の状態に保とうとすることがあります。ただし、スナップショットの分離は維持されます。