動的テーブルで不変性制約を使用する

不変性制約 により、動的テーブルの更新方法とタイミングをより細かく制御できます。制約により、テーブル全体が常に最新のクエリ結果を反映するのではなく、テーブルの一部が静的なままになります。

動的テーブルの特定の部分を不変としてマークすると、以下のタスクを実行できます。

  • 既存データへの更新または削除の伝播を防止します。

  • 条件を満たす行の挿入、更新、削除を制限します。

  • テーブルの他の部分の増分更新を有効にしながら、将来の変更を制限します。

  • 不変性制約を持つ動的テーブルをバックフィルします。詳細については、 バックフィルを使用して動的テーブルを作成する をご参照ください。

テーブルの残りの部分(つまり、不変性の条件に一致しない行)は変更可能のままであり、リフレッシュ中に更新することができます。

不変性の制約を強制するには、 CREATE DYNAMIC TABLE または ALTER DYNAMIC TABLE コマンド実行時に IMMUTABLE WHERE パラメーターを指定します。IMMUTABLE WHERE 条件で参照される列はベーステーブルの列ではなく、動的テーブルの列である必要があります。たとえば、次の SQL ステートメントの IMMUTABLE WHERE 式は、 id ではなく id1 のみを使用できます。

CREATE DYNAMIC TABLE my_dynamic_table (id1 INT)
  TARGET_LAG = '20 minutes'
  WAREHOUSE = mywh
  IMMUTABLE WHERE ( <expr> )
  AS
    SELECT id AS id1 FROM staging_table;
Copy

行が可変かどうかを確認するには、 METADATA$IS_IMMUTABLE 列を使用します。例: SELECT * , METADATA$IS_IMMUTABLE FROM my_dynamic_table

動的テーブルの不変性制約を表示するには、SHOW DYNAMIC TABLES コマンドを実行します。immutable_where 列は、テーブルに設定された IMMUTABLE WHERE 制約、または何も設定されていない場合は NULL を表示します。

コンピューティングコストについては、不変性制約のコンピューティングコスト をご参照ください。

例:IMMUTABLE WHERE を使用して、ディメンションテーブルが変更された場合に古いデータの再計算を防ぐ

次の例では、ディメンションテーブルの行を更新すると、すべての履歴ファクトではなく、その行と結合する最終日のファクトが再処理されます。

CREATE DYNAMIC TABLE joined_data
  TARGET_LAG = '1 minute'
  WAREHOUSE = mywh
  IMMUTABLE WHERE (timestamp_col < CURRENT_TIMESTAMP() - INTERVAL '1 day')
  AS
    SELECT F.primary_key primary_key, F.timestamp_col timestamp_col, D.value dim_value
    FROM fact_table F
    LEFT OUTER JOIN dimension_table D USING (primary_key);
Copy

例:無制限の保持動的テーブルおよび制限付き保持ベーステーブル

次の例では、最近追加されたデータの限定ウィンドウを持つステージングテーブルと、解析およびフィルター処理されたすべてのデータを格納する動的テーブルを作成します。

CREATE TABLE staging_data (raw TEXT, ts TIMESTAMP);

CREATE DYNAMIC TABLE parsed_data
  TARGET_LAG = '1 minute'
  WAREHOUSE = mywh
  IMMUTABLE WHERE (ts < CURRENT_TIMESTAMP() - INTERVAL '7 days')
  AS
    SELECT parse_json(raw):event_id::string event_id, parse_json(raw):name::string name, parse_json(raw):region::string region, ts
    FROM staging_data WHERE region = 'US';

-- Delete old staging data using Task
CREATE TASK delete_old_staging_data
  WAREHOUSE = mywh
  SCHEDULE = '24 hours'
  AS
    DELETE FROM staging_data WHERE ts < CURRENT_TIMESTAMP() - INTERVAL '30 days';
Copy

例:IMMUTABLE WHERE を使用して、上流の動的テーブルがフルリフレッシュモードで実行中の場合に、下流の増分リフレッシュを有効にする

Pythonユーザー定義のテーブル関数( UDTFs )などの一部のクエリ構成では、動的テーブルをフルリフレッシュモードで実行する必要があります。通常、この制限は増分処理を妨げます。下流のテーブルを増分のままにするには、次の例で示されているように、 IMMUTABLE WHERE 句を使用して不変リージョンを定義します。このように、上流のテーブルでフルリフレッシュを必要とする場合でも、下流のテーブルはパフォーマンス最適化の恩恵を受けます。

CREATE FUNCTION my_udtf(x varchar)
  RETURNS TABLE (output VARCHAR)
  LANGUAGE PYTHON
  AS $$ ... $$;

CREATE DYNAMIC TABLE udtf_dt
  TARGET_LAG = '1 hour'
  WAREHOUSE = mywh
  REFRESH_MODE = FULL
  IMMUTABLE WHERE (ts < current_timestamp() - interval '1 day')
  AS
    SELECT ts, data, output, join_key FROM input_table, TABLE(my_udtf(data));

CREATE DYNAMIC TABLE incremental_join_dt
  TARGET_LAG = '1 hour'
  WAREHOUSE = mywh
  REFRESH_MODE = INCREMENTAL
  IMMUTABLE WHERE (ts < current_timestamp() - interval '1 day')
  AS
    SELECT * FROM udtf_dt JOIN dim_table USING (join_key);
Copy

不変性制約を設定する際の制限と考慮事項

  • IMMUTABLE WHERE 述語 は最初の更新中に無視されますが、後続のすべての更新には適用されます。フルリフレッシュモードでは、述語は条件に一致しない行のみに再計算を制限します。

  • ストリームとインクリメンタルリフレッシュの動的テーブルは、不変性制約を持つフルリフレッシュの動的テーブルから読み取ることができます。

  • IMMUTABLE WHERE 制約は制限なしでクローニング中および複製中にコピーされます。

  • 通常の動的テーブルの制限 はすべて、引き続き適用されます。さらに、次の制限が適用されます。

    • 存在できるのは動的テーブルの単一の IMMUTABLE WHERE 述語のみです。ALTER DYNAMIC TABLE ... SET IMMUTABLE WHERE コマンドを使った別の述語の設定が、既存の述語を置き換えます。

    • IMMUTABLE WHERE 制約には次の項目を含めることはできません。

      • サブクエリ。

      • CURRENT_TIMESTAMP()または CURRENT_DATE() のようなタイムスタンプ関数を除く非決定性関数。タイムスタンプ関数を使用する場合は、不変領域が時間の経過とともに縮小しないように使用する必要があります。例: TIMESTAMP_COL< CURRENT_TIMESTAMP() is allowed but TIMESTAMP_COL >CURRENT_TIMESTAMP() ではない。

      • ユーザー定義関数または外部関数。

      • メタデータ列。たとえば METADATA$ で始まるもの。

      • 集計の結果である列、ウィンドウ関数または非決定性関数、あるいはウィンドウ関数演算子を介して渡される列。以下の動的テーブルでは、col3 だけが IMMUTABLE WHERE 述語で使用できます。

        CREATE DYNAMIC TABLE aggregates TARGET_LAG = '1 minute' WAREHOUSE = mywh
          AS SELECT col3, SUM(col2) AS col2 FROM input_table
          GROUP BY col3;
        
        CREATE DYNAMIC TABLE window_fns TARGET_LAG = '1 minute' WAREHOUSE = mywh
          AS SELECT col3, SUM(col4) OVER (PARTITION BY col3 ORDER BY col4) AS col2, col5 FROM input_table;
        
        Copy
    • 設定できるのは動的テーブルの単一の IMMUTABLE WHERE 条件のみです。既存の述語を置き換えるには、次の例に示すように ALTER DYNAMIC TABLE コマンドを使用します。

      -- Set or replace an existing predicate:
      ALTER DYNAMIC TABLE my_dynamic_table SET IMMUTABLE WHERE ( <expr> );
      
      Copy
      -- Remove an existing predicate:
      ALTER DYNAMIC TABLE my_dynamic_table UNSET IMMUTABLE WHERE;
      
      Copy