演算子が増分リフレッシュする方法

以下のテーブルは、各演算子がどのように増分化されるのか(つまり、完全な結果の代わりに変更を生成する新しいクエリフラグメントに変換されるのか)、そのパフォーマンスとその他の考慮すべき重要な要因の概要を示しています。

演算子

増分

考慮事項

SELECT <スカラー式>

変更された行に式を適用することで増分されます。

パフォーマンスは良好で、特に考慮すべき点はありません。

WHERE <スカラー式>

変更された各行で述語を評価し、述語が真であるものだけを含めることによって増分されます。

パフォーマンスは通常良好です。コストは変更の大きさに応じて直線的に変化します。

非常に選択的なWHERE式で動的テーブルをリフレッシュすると、結果として動的テーブルが変更されなくても、ウェアハウスのアップタイムが必要になることがあります。これは、ソースのどの変更が述語を満たすかを判断するためにウェアハウスが必要になる場合があるためです。

FROM <ベーステーブル>

前回のリフレッシュ以降にテーブルに追加または削除されたマイクロパーティションをスキャンすることで増分されます。

コストは、追加または削除されたマイクロパーティション内のデータ量に比例します。

推奨事項:

  • リフレッシュごとの変更量は、ソーステーブルの約5%に制限します。

  • 多くのマイクロパーティションに影響を与えるDMLsには注意してください。

<クエリ> 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;
Copy

上記のステートメントは次のように最適化できます:

CREATE DYNAMIC TABLE intermediate
  AS
    SELECT date_trunc(minute, ts) ts_min, c1 FROM table;
Copy
CREATE DYNAMIC TABLE sums
  AS
    SELECT ts_min, sum(c1) FROM intermediate
    GROUP BY 1;
Copy

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は、片側で変更されたキーがもう片側で既に存在していたかどうかをチェックすることで増分されます。

推奨事項:

  • 結合の片側が頻繁に変更される場合、結合キーでもう片側をクラスタリングするとパフォーマンスが向上する可能性があります。

  • 変更頻度の高いテーブルを左側に配置します。

  • OUTERの反対側の変更を最小限に抑えるようにします。LEFTOUTERの場合、右側の変更を最小限に抑えます。

  • FULL結合では、局所性が非常に重要です。

LATERAL FLATTEN

変更された行にフラット化された演算子を適用してインクリメント。

パフォーマンスは通常良好です。コストは変更の大きさに応じて直線的に変化します。FROM <base table> 演算子と同じ一般的な考慮事項。