マテリアライズドビューの増分更新
この記事では、マテリアライズドビューでの増分更新のセマンティクスと要件の概要を説明し、増分更新をサポートする SQL 操作、キーワード、および句を特定します。 増分更新と完全更新の違いの説明や、マテリアライズドビューとストリーミングテーブルのどちらを選択するかについての推奨事項が含まれています。
パイプラインがどのように更新されるかの概要については、「パイプラインはどのように更新されますか?」を参照してください。
サーバレス パイプラインを使用してマテリアライズドビューの更新を実行する場合、多くのクエリを増分的に更新できます。 増分更新では、マテリアライズド・ビューの定義に使用されるデータソースの変更を検出し、その結果を増分的に計算することで、コンピュートのコストを節約します。
サーバレスコンピュートでの更新実行
更新操作は、操作がスタンドアロンとして定義されたか、またはLakeFlow Spark宣言型パイプラインで定義されたかに関係なく、サーバレスパイプラインで実行されます。
For standalone materialized views, your workspace does not need to be enabled for serverless Lakeflow Spark Declarative Pipelines. The refresh will use a serverless pipeline automatically.
Lakeflow Spark宣言型パイプラインを使用して定義されたマテリアライズドビューの場合、ベアレスを使用するようにパイプラインを構成する必要があります。 「サーバレス パイプラインの構成」を参照してください。
マテリアライズドビューの更新セマンティクスは何ですか?
Materialized views guarantee equivalent results to batch queries. For example, consider the following aggregate query:
SELECT account_id,
COUNT(txn_id) txn_count,
SUM(txn_amount) account_revenue
FROM transactions_table
GROUP BY account_id
任意のDatabricks製品を使用してこのクエリを実行すると、結果はバッチセマンティクスを使用してコンピュートされ、ソースのtransactions_table内のすべてのレコードを集約します。これは、すべてのソースデータが1回の操作でスキャンおよび集約されることを意味します。
一部の Databricks 製品では、最後のクエリが実行された後にデータソースが変更されていない場合、セッション内またはセッション間で結果が自動的にキャッシュされます。 自動キャッシュ動作は、マテリアライズドビューとは異なります。
次の例では、このバッチクエリをマテリアライズドビューに変換します。
- SQL
- Python
CREATE OR REPLACE MATERIALIZED VIEW transaction_summary AS
SELECT account_id,
COUNT(txn_id) txn_count,
SUM(txn_amount) account_revenue
FROM transactions_table
GROUP BY account_id
@dp.materialized_view()
def transaction_summary():
return (spark.read.table("transactions_table")
.groupBy("account_id")
.agg(
count("*").alias("txn_count"),
sum("txn_amount").alias("account_revenue")
)
)
マテリアライズドビューを更新すると、コンピュートの結果はバッチ・クエリ・セマンティクスと同一になります。 このクエリは、増分更新が可能なマテリアライズドビューの例です。つまり、更新操作では、ソース データ内の新しいデータまたは変更されたデータのみを処理して結果をコンピュートするベスト エフォート transactions_table 試みます。
マテリアライズドビューのデータソースに関する考慮事項
マテリアライズドビューはあらゆるデータソースに対して定義できますが、すべてのデータソースがマテリアライズドビューに適しているわけではありません。以下の注意点と推奨事項を考慮してください。
マテリアライズドビューは、サポートされている操作の結果を段階的に更新するためのベストエフォート型の試みを行います。データソースの一部の変更には、完全な更新が必要です。フル更新を実行する代わりに失敗する更新ポリシーを定義できます。
マテリアライズドビューのすべてのデータソースは、マテリアライズドビューを定義するクエリが増分更新をサポートしている場合でも、完全更新セマンティクスに対して堅牢である必要があります。
-
フルリフレッシュがコストがかかりすぎるクエリの場合、厳密に1回限りの処理を保証するために、ストリーミングテーブルを使用してください。例には大規模なテーブルが含まれます。
-
レコードが1回のみ処理される必要がある場合、マテリアライズドビューをデータソースに対して定義しないでください。そうではなく、ストリーミングテーブルを使用してください。以下に例を挙げます。
- Kafka などのデータ履歴を保持しないデータソースです
- クラウドオブジェクトストレージからデータを取り込むためにAuto Loaderを使用するクエリなどの取り込み操作です。
- 処理後にデータを削除またはアーカイブする予定があるものの、下流のテーブルに情報を保持する必要があるあらゆるデータソースです。たとえば、特定のしきい値よりも古いレコードを削除する予定の日付パーティションテーブル。
-
すべてのデータソースが増分更新をサポートしているわけではありません。以下のデータソースは増分更新をサポートしています。
- Delta テーブルには、Unity Catalog マネージドテーブル、および Delta Lake を基盤とする外部テーブルが含まれます。
- マテリアライズドビュー。
- Streaming tables, including the targets of
AUTO CDC ... INTOoperations. - Unity Catalog マネージド Iceberg テーブル(v2 および v3)です。Iceberg v3は、最適な増分更新のサポートに推奨されます。Apache Iceberg v3 機能を使用を参照してください。フォーリン Iceberg テーブルはサポートされていません。
-
一部の増分更新操作では、クエリされたデータソースで行トラッキングを有効にする必要があります。 行トラッキングは、マテリアライズドビュー、ストリーミングテーブル、Unity Catalog マネージドテーブルなどのDeltaテーブルでのみサポートされているDelta Lakeの機能です。Databricks の行追跡を参照してください。
-
行フィルターまたは列マスクが定義されているデータソースでは、増分更新はサポートされていません。行フィルターと列マスクを参照してください。
マテリアライズドビューの最適化
最高のパフォーマンスを得るには、Databricksは、すべてのマテリアライズドビューソーステーブルで以下の機能を有効にすることをお勧めします。
これらの機能は、作成中に設定することも、または後で ALTER TABLE ステートメント (Databricks SQLから実行します) を使用して設定することもできます。例えば:
ALTER TABLE <table-name> SET TBLPROPERTIES (
delta.enableDeletionVectors = true,
delta.enableRowTracking = true,
delta.enableChangeDataFeed = true);
マテリアライズドビューの更新タイプ
マテリアライズドビューが更新されると、更新または完全更新を指定できます。
- 更新は増分更新を試みますが、必要に応じて完全更新を行います。増分更新は、接続されているコンピュートがサーバレスの場合にのみ利用できます。
- フル更新は、マテリアライズドビューへのすべての入力を常に再計算し、すべてのチェックポイントをリセットします。
更新で使用された更新タイプを判別するには、更新の更新タイプを判別するを参照してください。
デフォルト更新
サーバレスにおけるマテリアライズドビューのデフォルトの更新は、増分更新を実行しようとします。増分更新は、最後の更新後に基になるデータの変更を処理し、そのデータをテーブルに追加します。ベーステーブルと含まれる操作によっては、特定タイプのマテリアライズドビューのみが増分更新できます。増分更新が不可能な場合、または接続されているコンピュートがサーバレスではなくクラシックである場合、完全な再計算が実行されます。
Databricks は完全更新または増分更新を適用します。決定は、どちらのオプションがより費用対効果が高いか、およびクエリが増分更新をサポートしているかどうかに基づいています。この動作を変更するには、更新ポリシーを参照してください。
増分更新の出力と完全再計算は同じです。Databricksは、増分更新とフル再計算のより安価な方を選択するためにコスト分析を実行します。
サーバレス パイプラインを使用して更新されたマテリアライズドビュー のみが増分更新を使用できます。サーバレス パイプラインを使用しないマテリアライズドビューは、常に完全に再計算されます。
SQLwarehouse またはLakeflow Spark SQL型パイプラインを使用してマテリアライズドビューを作成すると、クエリがサポートされている場合、 Databricksそれらを段階的に更新します。 クエリでサポートされていない式が使用されている場合、Databricks は代わりに完全な再計算を実行するため、コストが増加する可能性があります。
更新で使用された更新タイプを判別するには、更新の更新タイプを判別するを参照してください。
フルリフレッシュ
完全更新を実行すると、テーブルとチェックポイントがクリアされ、ソースで使用可能なすべてのデータが再処理されるため、マテリアライズドビューの結果が上書きされます。
Databricks SQL を使用して定義されたマテリアライズドビューのフル更新を実行するには、次の構文を使用します。
REFRESH MATERIALIZED VIEW mv_name FULL
Lakeflow Spark宣言型パイプラインで定義されたマテリアライズドビューの場合、選択したデータセットまたはパイプライン内のすべてのデータセットに対して完全な更新を実行することを選択できます。 パイプライン更新セマンティクスを参照してください。
データ保持しきい値または手動削除によりレコードが削除されたデータソースに対してフルリフレッシュを実行した場合、削除されたレコードはコンピュートの結果に反映されません。ソースでデータが使用できなくなった場合、古いデータを回復できない場合があります。これにより、ソースデータに存在しなくなった列のスキーマも変更される場合があります。
マテリアライズドビューの増分更新のサポート
次の表は、SQLキーワードまたは句別の増分更新のサポートを示しています。特定のクエリの増分性をテストするには、CREATE MATERIALIZED VIEWを使用できます。
一部のキーワードと句では、クエリ対象のデータソースで行トラッキングを有効にする必要があります。 Databricks の行追跡を参照してください。
以下の表では、これらのキーワードと節に星印(*)が付いています。
SQL キーワードまたは句 | PySpark データフレーム相当 | Support for incremental refresh |
|---|---|---|
|
| はい、決定的な組み込み関数および不変のユーザー定義関数(UDF)を含む式がサポートされています。 |
|
| はい |
| データフレーム変数の連結 | はい、共通テーブル式はサポートされています。 |
| N/A | いいえ、再帰 CTE を使用するマテリアライズドビューは増分更新の対象外であり、フル再計算にフォールバックします。 |
|
| はい |
|
| サポートされているベーステーブルには、Deltaテーブル、Unity Catalog マネージド Iceberg テーブル、マテリアライズドビュー、およびストリーミングテーブルがあります。 |
|
|
|
|
| はい |
|
| はい |
|
| はい |
|
| はい |
|
| はい。ウィンドウ関数で増分処理を行うには、 |
|
| はい |
|
| はい、期待を含むマテリアライズドビューは増分更新が可能です。ただし、増分更新は次の場合にはサポートされていません。
|
UDF | UDF | Databricks は、UDF の動作が変更されたことを検出すると、完全な更新を実行します。ただし、他の関数やライブラリを呼び出す UDF は、Databricks では認識できない形で動作が変更される可能性があります。UDF の動作が変更された場合、更新された UDF を完全なマテリアライズドビューに適用するためには、完全な更新を実行する必要があります。 |
非決定論的関数 | 非決定論的関数 | 非決定性時間関数は |
サポートされていないソース | サポートされていないソース | Sources such as volumes, external locations, and foreign catalogs are not supported. Foreign Iceberg tables are not supported. Unity Catalog managed Iceberg tables are supported. |
アップデートの更新タイプの判断
マテリアライズドビューの更新のパフォーマンスを最適化するために、Databricks はコスト モデルを使用して、更新に使用する手法を選択します。 次の表では、これらの手法について説明します。
テクニック | 増分更新か? | 説明 |
|---|---|---|
| No | マテリアライズドビューは完全に再計算されました |
| 該当なし | マテリアライズドビューは更新されませんでした。これは、ベース・テーブルへの変更が検出されなかったためです。 |
いずれか:
| はい | マテリアライズドビューは、指定された手法を使用して増分更新されました。 |
更新ポリシーも参照してください。
使用されている手法を確認するには、 event_typeがplanning_informationであるLakeflow Spark宣言型パイプライン イベント ログをクエリします。
SELECT
timestamp,
message
FROM
event_log(TABLE(<fully-qualified-table-name>))
WHERE
event_type = 'planning_information'
ORDER BY
timestamp desc;
<fully-qualified-table-name> を、カタログやスキーマなど、マテリアライズドビューの完全修飾名に置き換えます。
このコマンドの出力例:
timestamp | message |
|---|---|
|
|
パイプラインイベントログを参照してください。
更新ポリシー
デフォルトでは、Databricksは、クエリ構造、データ変更量、システムコストモデリングに基づいて、最も費用対効果の高い更新戦略(増分またはフル)を自動的に選択します。このデフォルトの動作は、手動設定なしで更新パフォーマンスを最適化します。
ただし、一部のワークロードでは、より予測可能または明示的に制御された更新動作が必要です。これらのシナリオをサポートするには、マテリアライズドビューの定義に REFRESH POLICY を指定できます。更新ポリシーは、Databricksが増分更新を実行するかどうか、いつフルリフレッシュにフォールバックする可能性があるか、およびフル再計算を実行せずに更新を失敗させるべきかどうかを制御します。
REFRESH POLICYを使用して、システムを構成できます。
AUTO(デフォルト) 自動でコストベースの選択が使用されます。Databricks は、効率とクエリ機能に基づいて増分更新または完全更新を選択します。ほとんどのユーザーに推奨されます。INCREMENTAL増分更新をおすすめします。Databricks は可能な限り増分更新を実行します。クエリプランが増分更新をサポートしなくなった場合、フルリフレッシュが実行されます。INCREMENTAL STRICT- 増分更新が厳密に必須です。増分更新は、通常の運用中に必要です。増分更新ができない場合、更新または作成操作が失敗します。FULL- 必ず完全更新を実行してください。Databricks は、クエリが増分可能である場合でも、増分更新を行うことはありません。
- SQL
- Python
-- Create a materialized view with an incremental refresh policy
CREATE MATERIALIZED VIEW IF NOT EXISTS my_mv
REFRESH POLICY INCREMENTAL
AS SELECT a, sum(b) FROM my_catalog.example.my_table GROUP BY a;
from pyspark import pipelines as dp
@dp.materialized_view(
refresh_policy = 'incremental_strict'
)
def my_mv():
return spark.read("main.default.source_table")
最適な更新ポリシーはワークロード特性によって異なります:
AUTOほとんどのワークロードに適しています。コストとパフォーマンスのバランスを取り、クエリの動作が変化すると自動的に適応します。INCREMENTAL増分更新がメリットをもたらす場合に有用ですが、増分更新が一時的に利用できない場合(例えば、ソーステーブルで行追跡が無効になっている場合)でも、Databricks が完全更新を実行することは許容されます。INCREMENTAL STRICTコスト、パフォーマンス、またはSLAの制約を満たすために増分更新が必要であり、かつ予期しない完全更新が許容できない場合に使用すべきです。このポリシーは、ユーザーが更新の失敗を希望し、フル更新に進むのではなく問題をデバッグできるようにする場合に推奨されます。FULLis suitable when incremental refresh provides little benefit, the dataset is small, or the query structure frequently changes in ways that prevent incrementalization.
詳細と構文については、REFRESH ポリシー句(パイプライン)、またはデータセットがDatabricks SQLで定義されている場合は、REFRESH ポリシー句を参照してください。