動的テーブルのパフォーマンスの最適化

このトピックでは、動的テーブルのパフォーマンスを最適化するための手法を設計の変更と調整に分けて説明します。

動的テーブルを最適化する前に、リフレッシュが遅い原因を診断することをお勧めします。ステップバイステップのワークフローについては 遅いリフレッシュを診断 をご参照ください。

パフォーマンスカテゴリの背景については、 パフォーマンスの意思決定 をご参照ください。

設計の変更

設計の変更には動的テーブルの再作成が必要ですが、パフォーマンスへの影響は大きくなります。

注釈

増分変更を行う代わりに、変更をグループ化してテーブルを再作成することをお勧めします。

リフレッシュモードを選択

選択したリフレッシュモードは、各リフレッシュ中にSnowflakeが処理するデータ量を決定するため、パフォーマンスに大きな影響を与えます。各モードの仕組みについては、 動的テーブルのリフレッシュモード をご参照ください。

重要

インクリメンタルリフレッシュを備えた動的テーブルは、フルリフレッシュを使用する動的テーブルの下流にはできません。

以下の決定プロセスを使用して、リフレッシュモードを選択します。

  1. サポートされているクエリコンストラクト のリストに対してクエリを確認してください。すべてのクエリ演算子がインクリメンタルリフレッシュをサポートしているわけではありません。サポート されている 演算子については、 インクリメンタルリフレッシュ向けにクエリを最適化する を参照し、パフォーマンスにどのように影響するかを理解してください。

  2. 変更量を推定します。これは、リフレッシュ間に変更されるデータの割合です。たとえば、インクリメンタルリフレッシュは、データの変更が5%未満の場合に最適です。

  3. データの局所性を評価します。ソーステーブルが、結合で使用する予定のキーによってクラスター化されているかどうかを確認します。動的テーブルクエリのGROUP BYまたはPARTITION BY句です。局所性が悪いとインクリメンタルリフレッシュの効率が低下します。局所性を向上させるには、 データの局所性を向上させる をご参照ください。

  4. 以下の表に基づいてモードを選択します。

    モード

    使用するタイミング

    インクリメンタル

    クエリはサポートされている演算子を使用します。リフレッシュ間のデータ変更は5%未満であり、ソーステーブルのデータ局所性は良好です。

    注釈

    インクリメンタルリフレッシュは、変更された行だけでなく、ソーステーブルをスキャンすることもできます。たとえば、結合の片側の新しい行は、もう一方のテーブルのすべての行と一致する必要があります。少数の変更でも、大幅な作業をトリガーする可能性があります。

    フル

    データの変更の割合が大きい、クエリでサポートされていない演算子が使用されている、またはデータの局所性がありません。

    自動

    プロトタイプまたはテスト中。Snowflakeのリリース間で動作が変更される可能性があるため、実稼働環境ではAUTOを避けてください。

  5. 動的テーブルを作成する際は、CREATE DYNAMIC TABLEステートメントで、 REFRESH_MODE = INCREMENTAL または REFRESH_MODE = FULL によってモードを指定します。

動的テーブルがどのリフレッシュモードを使用するかを確認するには、 リフレッシュモード をご参照ください。

クエリとパイプラインを最適化する

動的テーブルクエリとパイプラインの構造は、リフレッシュのパフォーマンスに直接影響します。次のガイドラインを使用して、各リフレッシュの作業を軽減します。

個々のクエリを簡素化する

  • 外部結合ではなく内部結合を使用します。内部結合はインクリメンタルリフレッシュの方が有効です。外部結合を回避するために、ソースデータの参照整合性を確認します。

  • 不要な操作は避けます。冗長なDISTINCT句および未使用の列を削除します。頻繁にクエリされていない、幅の大きい列を削除します(大規模なJSON BLOBなど)。

  • 効率的に重複を削除します。可能な場合、DISTINCTの代わりにランキング関数を使用します。

SQL演算子がインクリメンタルリフレッシュのパフォーマンスにどのように影響するかに関する詳細なガイダンスについては、 インクリメンタルリフレッシュ向けにクエリを最適化する をご参照ください。

動的テーブル間で変換を分割する

複雑な変換を複数の動的テーブルに分割すると、ボトルネックの特定が容易になり、デバッグ性が向上します。不変性制約 では、ステージごとに異なるリフレッシュモードを使用することもできます。

  • 早期にフィルターを追加します。ソースデータに最も近い動的テーブルに WHERE 句を摘要し、下流のテーブルで処理される行数を少なくします。

  • 下流テーブルで DISTINCT 操作の繰り返しを回避するには、パイプラインの早い段階で重複した行を削除します。

  • テーブルごとの操作数を減らします。結合、集計、またはウィンドウ関数を1つのクエリですべて結合するのではなく、中間の動的テーブルに移動します。

  • 複合式( DATE_TRUNC('minute', ts) など)でグループ化する前に、中間テーブルで実体化します。詳細については、 集計を最適化する をご参照ください。

注釈

最適な分割ポイントを見つけるには、試行錯誤が必要です。

GROUP BYDISTINCTPARTITION BY を備えたウィンドウ関数、結合など、異なるキーでデータをシャッフルする操作に分割することを検討してください。これにより、各動的テーブルはキー操作により良いデータ局所性を維持できるようになります。演算子固有のガイダンスについては、 インクリメンタルリフレッシュ向けにクエリを最適化する をご参照ください。

次の例では、複雑なクエリを中間の動的テーブルに分割する方法を示します。

初期の複雑なクエリ:

CREATE DYNAMIC TABLE final_result
  TARGET_LAG = '1 hour'
  WAREHOUSE = my_warehouse
AS
  SELECT ...
  FROM large_table a
  JOIN dimension_table b ON ...
  JOIN another_table c ON ...
  GROUP BY ...;
Copy

中間の動的テーブルを追加して、複雑なパイプラインを分割します。

CREATE DYNAMIC TABLE intermediate_joined
  TARGET_LAG = DOWNSTREAM
  WAREHOUSE = my_warehouse
AS
  SELECT ...
  FROM large_table a
  JOIN dimension_table b ON ...;

CREATE DYNAMIC TABLE final_result
  TARGET_LAG = '1 hour'
  WAREHOUSE = my_warehouse
AS
  SELECT ...
  FROM intermediate_joined
  JOIN another_table c ON ...
  GROUP BY ...;
Copy

演算子がパフォーマンスにどのように影響するかについての詳細と例については、 インクリメンタルリフレッシュ向けにクエリを最適化する をご参照ください。

履歴データを不変とマークする

IMMUTABLE WHERE 句を使用して、Snowflakeに特定の行が変更されないことを指示します。これにより、各リフレッシュ時の作業範囲が短縮されます。

構文、例、詳細なガイダンスについては、 不変性制約の使用 をご参照ください。

調整

調整のために、動的テーブルを再作成する必要はありません。パイプラインの実行中に調整できます。

ウェアハウスの構成を調整する

CREATE DYNAMIC TABLE ステートメントで指定するウェアハウスは、そのテーブルのすべてのリフレッシュを実行します。ウェアハウスのサイズと構成は、更新時間とコストに直接影響します。

ウェアハウスと動的テーブルの詳細については、 動的テーブルのウェアハウスの使用を理解する をご参照ください。一般的なウェアハウスのパフォーマンス最適化戦略については、 パフォーマンスに対するウェアハウスの最適化 をご参照ください。

初期化に別のウェアハウスを使用する

初期リフレッシュは、インクリメンタルリフレッシュよりも大幅に多くのデータを処理することがよくあります。INITIALIZATION_WAREHOUSEを使用して、より大きなウェアハウスで初期化を実行します。定期的なリフレッシュのために、より小さく、より費用対効果の高いウェアハウスを予約します。

CREATE DYNAMIC TABLE my_dynamic_table
  TARGET_LAG = 'DOWNSTREAM'
  WAREHOUSE = 'XS_WAREHOUSE'
  INITIALIZATION_WAREHOUSE = '4XL_WAREHOUSE'
  AS <query>;
Copy

既存の動的テーブルの初期化ウェアハウスを追加または変更するには、以下を行います。

ALTER DYNAMIC TABLE my_dynamic_table SET INITIALIZATION_WAREHOUSE = '4XL_WAREHOUSE';
Copy

初期化ウェアハウスを削除し、すべてのリフレッシュにプライマリウェアハウスを使用するには、以下を行います。

ALTER DYNAMIC TABLE my_dynamic_table UNSET INITIALIZATION_WAREHOUSE;
Copy

ウェアハウスの構成を表示するには、 SHOW DYNAMIC TABLES を使用するか、 DYNAMIC_TABLE_REFRESH_HISTORY テーブル関数を確認します。

必要に応じてサイズを変更する

コストとパフォーマンスのバランスをとるには、バイトのスピルを防止する一方で、ワークロードが並行して使用できるサイズを超えないウェアハウスサイズを選択します。より高速なリフレッシュが重要な場合は、コスト最適化のポイントを少し超えてサイズをわずかに増やします。

動的テーブルリフレッシュに関する考慮事項:

  • スピルしたバイト数の割合 :クエリ履歴にローカルストレージまたはリモートストレージにスピルされたバイトが表示されている場合は、更新中にウェアハウスのメモリが不足しています。より大きなウェアハウスは、流出を防ぐためにより多くのメモリを提供します。詳細については、 大きすぎてメモリに収まらないクエリ をご参照ください。

  • 初期リフレッシュが遅い :初期リフレッシュが遅い場合は、初期作成向けにINITIALIZATION_WAREHOUSEを設定するか、一時的にウェアハウスのサイズを変更し、その後テーブルの作成後にウェアハウスのサイズを変更することを検討します。

  • 飽和並列 :ある点を過ぎると、並列化を増やしても見返りは少なくなります。ウェアハウスのサイズを2倍にすると、ランタイムを半分にせずにコストが2倍になる可能性があります。リフレッシュがどのように並列処理を使用しているかを確認するには、 クエリプロファイル を確認してください。

ウェアハウスのサイズを変更するには、 ウェアハウスサイズの拡大 をご参照ください。

コスト考慮については、 仮想ウェアハウスのクレジット使用状況 および ウェアハウスの操作 をご参照ください。

マルチクラスターウェアハウスで同時リフレッシュを処理する

複数の動的テーブルがウェアハウスを共有し、キューを頻繁にリフレッシュする場合は、 マルチクラスターウェアハウス の使用を検討してください。マルチクラスターウェアハウスは、クエリがキューに入れられるとクラスターを自動的に追加し、需要が落ちると削除します。これにより、静止期間に未使用の容量を支払うことなく、ピーク期間のリフレッシュレイテンシを改善することができます。

キューを特定して減らすためのガイダンスについては、 キューの削減 をご参照ください。

マルチクラスターウェアハウスにはEnterprise Edition(またはそれ以上)が必要です。コスト考慮については、 マルチクラスターウェアハウスのスケーリングポリシーの設定 をご参照ください。

適切なターゲットラグの特定

ターゲットラグは動的テーブルのリフレッシュ頻度を制御します。ターゲットラグが短いほど、データの鮮度が高くなりますが、リフレッシュの頻度が高く、コンピューティングコストが高くなります。ターゲットラグの仕組みの詳細については、 動的テーブルのターゲット・ラグの理解 をご参照ください。

以下の推奨事項を使用して、ワークロードのターゲットラグを最適化します。

  • 独立した鮮度保証を必要としない 中間テーブルにはDOWNSTREAMを使用します 。これらのテーブルは、下流のテーブルで必要な場合にのみリフレッシュされます。

  • 適切なラグを見つけるために、リフレッシュ履歴をチェックするDYNAMIC_TABLE_REFRESH_HISTORY または Snowsight を使用して、リフレッシュ時間とリフレッシュのスキップを分析します。ターゲットラグを通常のリフレッシュ時間より少し高く設定します。

ターゲットラグを変更

ALTER DYNAMIC TABLE my_dynamic_table SET TARGET_LAG = '1 hour';
Copy

下流の需要に基づいてリフレッシュするように動的テーブルを設定するには、以下を行います。

ALTER DYNAMIC TABLE my_dynamic_table SET TARGET_LAG = DOWNSTREAM;
Copy

データの局所性を向上させる

局所性 は、Snowflakeが同じキー値を共有する行をどの程度密接に格納するかを表します。キーが一致する行のマイクロパーティションの数が少ない場合(局所性が高い場合)、インクリメンタルリフレッシュでスキャンされるデータは少なくなります。一致するキーが多くのマイクロパーティションにまたがっている場合(局所性が悪い)、インクリメンタルリフレッシュはフルリフレッシュよりも時間がかかることがあります。

Snowflakeがデータを保存する方法の詳細については、 マイクロパーティションとデータクラスタリング をご参照ください。

クラスターソーステーブル

局所性を向上させる最も効果的な方法は、動的テーブルクエリで使用されたキーでソーステーブルをクラスター化することです(JOIN、GROUP BY、またはPARTITION BYキー)。

ALTER TABLE my_source_table CLUSTER BY (join_key_column);
Copy

複数の列で結合し、すべてでクラスタリングできない場合:

  • 最も選択的なキーによる、大きなテーブルのクラスタリングを優先します。

  • 異なる動的テーブルで使用するために、異なるキーでクラスタリングされた同じデータの個別のコピーを作成することを検討してください。

詳細については、 クラスタリングキーとクラスタ化されたテーブル をご参照ください。自動再クラスタリングを有効にするには、 自動クラスタリング をご参照ください。

局所性に影響する要因

ソーステーブルのクラスタリング以外に、他の2つの要因が局所性に影響します。これらはデータパターンに依存しており、直接変更することは困難です。

  • 新しいデータとパーティションキーの整合性 :新しい行がテーブルのごく一部にのみ影響する場合、インクリメンタルリフレッシュが高速です。これはクエリ構造ではなく、データインジェスチョンパターンによって異なります。

    たとえば、時間別にグループ化された時系列データは、新しい行が最近のタイムスタンプを共有するため、良い局所性を備えています。テーブル全体に値が分散している列でグループ化されたデータは、局所性が低くなります。

  • 動的テーブルクラスタリングと変更する方法 :Snowflakeが動的テーブルに更新や削除を適用する場合は、影響を受ける行を特定する必要があります。これは、変更された行が近接して格納されている場合に高速です。

    たとえば、最近の行の更新は、動的テーブルが時間的に自然に順序付けられている場合に良好に実行されます。テーブル全体に分散された更新は遅くなります。この要因は、どの行が変更されるか、その頻度など、ワークロードパターンに依存します。

これらの要因により局所性が低下した場合は、上流でデータモデルやインジェスチョンパターンを調整できるかどうかを検討してください。