Erläuterungen zum Aktualisieren von dynamischen Tabellen

Die Inhalte dynamischer Tabellen basieren auf den Ergebnissen bestimmter Abfragen. Wenn sich die zugrunde liegenden Daten, auf denen die dynamische Tabelle basiert, ändern, wird die Tabelle aktualisiert, um diese Änderungen widerzuspiegeln. Diese Aktualisierungen werden als Auffrischung (engl. refresh) bezeichnet. Dieser Prozess ist automatisiert und umfasst die Analyse der Abfrage, die der Tabelle zugrunde liegt.

Timeouts beim Aktualisieren dynamischer Tabellen werden durch den Parameter STATEMENT_TIMEOUT_IN_SECONDS bestimmt, der die maximale Dauer für das Konto oder Warehouse festlegt, bevor die Aktualisierung automatisch abgebrochen wird.

In den folgenden Abschnitten wird das Aktualisieren dynamischer Tabellen näher erläutert:

Aktualisierungsmodi für dynamische Tabellen

Die Aktualisierung einer dynamischen Tabelle kann auf eine von zwei Arten erfolgen:

  1. Inkrementelle Aktualisierung: Dieser automatische Prozess analysiert die Abfrage der dynamischen Tabelle und berechnet die Änderungen seit der letzten Aktualisierung. Anschließend werden diese Änderungen in die Tabelle eingefügt. Weitere Informationen zu unterstützten Abfragen finden Sie unter Unterstützte Abfragen bei der inkrementellen Aktualisierung.

  2. Vollständige Aktualisierung: Wenn der automatisierte Prozess keine inkrementelle Aktualisierung ausführen kann, wird eine vollständige Aktualisierung ausgeführt. Dabei wird die Abfrage für die dynamische Tabelle ausgeführt und die vorherigen materialisierten Ergebnisse werden vollständig ersetzt.

Die in der Abfrage verwendeten Konstrukte bestimmen, ob eine inkrementelle Aktualisierung verwendet werden kann. Nachdem Sie eine dynamische Tabelle erstellt haben, können Sie die Tabelle überwachen, um festzustellen, ob zur Aktualisierung dieser Tabelle inkrementelle oder vollständige Aktualisierungen verwendet werden.

Erläuterungen zur Zielverzögerung

Die Aktualisierung dynamischer Tabellen wird ausgelöst, je nachdem, wie veraltet die Daten sind, was gemeinhin als Zielverzögerung (engl. target lag) bezeichnet wird. Die Zielverzögerung für eine dynamische Tabelle wird relativ zu den Basistabellen an der Wurzel (root) des Diagramms gemessen, nicht zu den dynamischen Tabellen direkt davor. Snowflake plant die Aktualisierungen so, dass die tatsächliche Verzögerung Ihrer dynamischen Tabellen unter der Zielverzögerung bleibt. Die Dauer der einzelnen Aktualisierungen hängt von der Abfrage, dem Datenmuster und der Warehouse-Größe ab. Berücksichtigen Sie bei der Wahl der Zielverzögerung die Zeit, die benötigt wird, um jede dynamische Tabelle in einer Kette bis zur Root zu aktualisieren. Wenn Sie dies nicht tun, werden möglicherweise einige Aktualisierungen übersprungen, was zu einer höheren tatsächlichen Verzögerung führt.

Das Diagramm der Tabellen, die mit Ihrer dynamischen Tabelle verbunden sind, finden Sie unter Verwenden von Snowsight zum Untersuchen des Task-Graphen von dynamischen Tabellen.

Für das Angeben der Zielverzögerung gibt es zwei Möglichkeiten:

  1. Measure der Aktualität: Definiert die maximale Zeitspanne, die der Inhalt der dynamischen Tabelle hinter den Aktualisierungen der Basistabellen zurückbleiben darf.

    Im folgenden Beispiel wird die dynamische Tabelle product so eingestellt, dass sie stündlich aktualisiert wird:

    ALTER DYNAMIC TABLE product SET TARGET_LAG = '1 hour';
    
    Copy
  2. Downstream: Gibt an, dass die dynamische Tabelle bei Bedarf aktualisiert werden soll, wenn andere abhängige dynamische Tabellen aktualisiert werden. Diese Aktualisierung kann durch eine manuelle oder geplante Aktualisierung einer nachgelagerten dynamischen Tabelle ausgelöst werden.

    Im folgenden Beispiel basiert product auf anderen dynamischen Tabellen und ist so eingestellt, dass es auf der Grundlage der Zielverzögerung seiner nachgelagerten dynamischen Tabellen aktualisiert wird:

    ALTER DYNAMIC TABLE product SET TARGET_LAG = DOWNSTREAM;
    
    Copy

Die Zielverzögerung ist umgekehrt proportional zur Aktualisierungshäufigkeit der dynamischen Tabelle: häufige Aktualisierungen bedeuten eine geringere Verzögerung.

Betrachten Sie das folgende Beispiel, bei dem die dynamische Tabelle 2 (DT2) auf der Grundlage der dynamischen Tabelle 1(DT1) definiert wird. DT2 muss von DT1 lesen, um seine Inhalte zu materialisieren. Darüber hinaus nutzt ein Bericht über eine Abfrage Daten aus DT2.

Einfaches Beispiel mit zwei dynamischen Tabellen, wobei DT2 auf Grundlage von DT1 definiert ist.

Die folgenden Ergebnisse sind möglich, je nachdem, wie jede dynamische Tabelle ihre Verzögerung angibt:

Dynamische Tabelle 1 (DT1)

Dynamische Tabelle 2 (DT2)

Ergebnisse der Aktualisierung

TARGET_LAG = DOWNSTREAM

TARGET_LAG = 10minutes

DT2 wird höchstens alle 10 Minuten aktualisiert. DT1 leitet ihren Rückstand (Verzögerung) von DT2 ab und wird jedes Mal aktualisiert, wenn DT2 Aktualisierungen benötigt.

TARGET_LAG = 10minutes

TARGET_LAG = DOWNSTREAM

Dieses Szenario sollte vermieden werden. Die Berichtsabfrage wird keine Daten erhalten. DT1 wird häufig aktualisiert und DT2 wird nicht aktualisiert, da es keine dynamische Tabelle gibt, die auf DT2 basiert.

TARGET_LAG = 5minutes

TARGET_LAG = 10minutes

DT2 wird etwa alle 10 Minuten mit Daten von DT1 aktualisiert, die höchstens 5 Minuten alt sind.

TARGET_LAG = DOWNSTREAM

TARGET_LAG = DOWNSTREAM

DT2 wird nicht regelmäßig aktualisiert, da DT1 keine nachgelagerten Objekte mit einer bestimmten Verzögerung hat.

Unterstützte Abfragen bei der inkrementellen Aktualisierung

In der Tabelle unten sind die Ausdrücke, Schlüsselwörter und Klauseln beschrieben, die derzeit inkrementelle Aktualisierungen unterstützen. Eine Liste der Abfragen, die inkrementelle Aktualisierungen nicht unterstützen, finden Sie unter Einschränkungen bei der Unterstützung der inkrementellen Aktualisierung.

Schlüsselwort/Klausel

Unterstützung für inkrementelle Aktualisierungen

WITH

Allgemeine Tabellenausdrücke (CTE), die inkrementelle Aktualisierungsfeatures verwenden, werden in der Unterabfrage unterstützt.

Ausdrücke in SELECT

Ausdrücke, einschließlich solcher, die deterministische integrierte Funktionen und unveränderliche benutzerdefinierte Funktionen verwenden.

FROM

Quelltabellen, Ansichten und andere dynamische Tabellen. Unterabfragen außerhalb von FROM-Klauseln (z. B. WHERE EXISTS)

OVER

Alle Fensterfunktionen.

WHERE/HAVING/QUALIFY

Filter mit denselben Ausdrücken, die auch in SELECT gültig sind.

JOIN (und andere Ausdrücke zum Verknüpfen von Tabellen)

Zu den unterstützten Join-Typen für die inkrementelle Aktualisierung gehören Inner Joins, Outer-Equi Joins, Cross Joins und laterales Vereinfachen (nur die nicht-statische FLATTEN-Tabellenfunktion). Sie können eine beliebige Anzahl von Tabellen in der Verknüpfung angeben, und Aktualisierungen aller Tabellen in der Verknüpfung werden in den Ergebnissen der Abfrage berücksichtigt.

Die Auswahl der vereinfachten SEQ-Spalte aus einem lateral vereinfachten Join wird für die inkrementelle Aktualisierung nicht unterstützt.

UNION ALL

Dynamische Tabellen unterstützen UNION ALL.

GROUP BY

Dynamische Tabellen unterstützen GROUP BY.

Wichtig

Wenn die Abfrage Ausdrücke verwendet, die für eine inkrementelle Aktualisierung nicht unterstützt werden, verwendet der automatische Aktualisierungsprozess stattdessen eine vollständige Aktualisierung, wodurch zusätzliche Kosten entstehen können. Weitere Informationen dazu, wie Sie den verwendeten Aktualisierungsmodus feststellen können, finden Sie unter Feststellen, ob inkrementelle oder vollständige Aktualisierung verwendet wird.

Das Ersetzen einer IMMUTABLE-UDF (benutzerdefinierte Funktion), während sie von einer dynamischen Tabelle verwendet wird, die eine inkrementelle Aktualisierung verwendet, führt zu undefiniertem Verhalten in dieser Tabelle. VOLATILE-UDFs werden bei der inkrementellen Aktualisierung nicht unterstützt.

Derzeit werden seitliche Verknüpfungen (Lateral Joins) bei der inkrementellen Aktualisierung nicht unterstützt. Sie können jedoch LATERAL mit FLATTEN() verwenden, indem Sie den Aktualisierungsmodus auf INCREMENTAL einstellen.

Beispiel:

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;
Copy

Bemerkung

Die Auswahl der vereinfachten SEQ-Spalte aus einem lateral vereinfachten Join wird für die inkrementelle Aktualisierung nicht unterstützt.

Inkrementelle Aktualisierungen durch Operatoren

Die folgende Tabelle zeigt, wie jeder Operator inkrementiert wird (d. h. wie er in ein neues Abfrage-Fragment umgewandelt wird, das Änderungen anstelle von vollständigen Ergebnissen generiert) sowie seine Leistung und andere wichtige Faktoren, die zu berücksichtigen sind.

Operator

Inkrementalisierung

Hinweise

SELECT <skalare Ausdrücke>

Inkrementalisiert durch Anwendung von Ausdrücken auf geänderte Zeilen.

Funktioniert gut, keine besonderen Hinweise.

WHERE <skalare Ausdrücke>

Inkrementalisiert, indem das Prädikat für jede geänderte Zeile ausgewertet wird und nur die Zeilen berücksichtigt werden, für die das Prädikat wahr ist.

Läuft im Allgemeinen gut. Die Kosten skalieren linear mit dem Umfang der Änderungen.

Die Aktualisierung einer dynamischen Tabelle mit einem hochselektiven WHERE-Ausdruck kann Warehouse-Betriebszeit erfordern, selbst wenn sich die resultierende dynamische Tabelle nicht ändert. Dies liegt daran, dass ein Warehouse erforderlich sein kann, um festzustellen, welche Änderungen in den Quellen das Prädikat erfüllen.

FROM <Basistabelle>

Inkrementalisiert durch Scannen von Mikropartitionen, die seit der letzten Aktualisierung zur Tabelle hinzugefügt oder aus ihr entfernt wurden.

Die Kosten skalieren linear mit dem Datenvolumen in den hinzugefügten oder externen Mikropartitionen.

Empfehlungen:

  • Begrenzen Sie das Änderungsvolumen pro Aktualisierung auf etwa 5 % der Quelltabelle.

  • Seien Sie vorsichtig mit DMLs, das Auswirkungen auf viele Mikropartitionen hat.

<Abfrage> UNION ALL <Abfrage>

Inkrementalisiert, indem alle Änderungen auf jeder Seite vereinigt werden.

Funktioniert gut, keine besonderen Hinweise.

WITH <CTE-Liste> <Abfrage>

Inkrementalisiert, indem die Änderungen jedes gemeinsamen Tabellenausdrucks (Common Table Expression) berechnet werden.

WITH macht komplexe Abfragen leichter lesbar, aber seien Sie vorsichtig, denn die Definition einer einzelner dynamischer Tabellen darf nicht zu komplex sein. Weitere Informationen dazu finden Sie unter Pipelines dynamischer Tabellen verketten und Optimieren der Leistung inkrementeller Aktualisierungen bei komplexen dynamischen Tabellen.

Skalare Aggregate

Skalare Aggregate werden derzeit nicht effizient inkrementalisiert. Wenn sich deren Eingaben ändern, werden sie vollständig neu berechnet.

GROUP BY <Schlüssel>

inkrementalisiert, indem die Aggregate für jeden Gruppierungsschlüssel, der sich geändert hat, neu berechnet werden.

Stellen Sie sicher, dass die Quelldaten nach den Gruppierungsschlüsseln geclustert sind und die Änderungen nur einen kleinen Teil (etwa <5 %) der Gruppierungsschlüssel ausmachen.

Wenn der Gruppierungsschlüssel einen zusammengesetzten Ausdruck und keine Basisspalte enthält, müssen inkrementelle Aktualisierungen möglicherweise eine große Menge an Daten durchsuchen. Um die Größe dieser Scans zu reduzieren, materialisieren Sie den Ausdruck in einer dynamischen Tabelle und wenden dann die Gruppierungsoperation auf die materialisierte Spalte in einer anderen dynamischen Tabelle an.

Nehmen Sie zum Beispiel die folgende zusammengesetzte Anweisung:

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

Die obige Anweisung kann wie folgt optimiert werden:

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

Äquivalent zu GROUP BY ALL, aber ohne Aggregatfunktionen.

Dies stellt oft eine erhebliche Optimierungsmöglichkeit dar.

Es ist eine gängige Praxis, DISTINCT großzügig in Abfragen einzusetzen, um zu vermeiden, dass versehentlich Duplikate eingefügt werden. Bei der inkrementellen Aktualisierung verbrauchen DISTINCT-Operationen immer wieder Ressourcen, da bei jeder Aktualisierung auf Duplikate geprüft werden muss.

Bei der Optimierung der Leistung kann das Auffinden und Entfernen redundanter DISTINCTs ein einfacher Gewinn sein. Sie können dies tun, indem Sie Duplikate weiter upstream beseitigen und die Kardinalität von Verknüpfungen sorgfältig prüfen.

<fn> OVER <Fenster>

Inkrementalisiert, indem die Fensterfunktion für jeden Partitionsschlüssel, der sich geändert hat, neu berechnet wird.

Stellen Sie sicher, dass Ihre Abfrage eine PARTITION BY-Klausel enthält und die Quelldaten nach Partitionsschlüsseln geclustert sind. Stellen Sie sicher, dass die Änderungen nur einen kleinen Teil (etwa <5 %) der Partitionen ausmachen.

<links> INNER JOIN <rechts>

Inkrementalisiert, indem die Änderungen auf der linken Seite mit der rechten Seite verknüpft und dann die Änderungen auf der rechten Seite mit der linken Seite verknüpft werden.

Wenn eine der Seiten der Verknüpfung klein ist, ist die Leistung wahrscheinlich gut. Wenn sich eine der Seiten der Verknüpfung häufig ändert, kann ein Clustering der anderen Seite nach dem Verknüpfungsschlüssel die Leistung verbessern.

<links> [{LEFT | RIGHT | FULL }] OUTER JOIN <rechts>

Inkrementalisiert durch Factoring in einen inner-join union-all-ed mit einem oder zwei NOT EXISTS, um NULL-Werte für Nicht-Übereinstimmungen zu berechnen. Diese faktorisierte Abfrage wird dann inkrementalisiert.

Die innere Verknüpfung wird wie gezeigt inkrementalisiert. Die Nicht-Existenzen werden inkrementalisiert, indem geprüft wird, ob die geänderten Schlüssel auf der einen Seite bereits auf der anderen Seite existieren.

Empfehlungen:

  • Wenn sich eine der Seiten der Verknüpfung häufig ändert, kann ein Clustering der anderen Seite nach dem Verknüpfungsschlüssel die Leistung verbessern.

  • Legen Sie die Tabelle, die sich am häufiger ändert, auf die linke Seite.

  • Versuchen Sie, die Veränderungen auf der Seite, die OUTER gegenüberliegt, zu minimieren. Minimieren Sie also für LEFT OUTER die Änderungen auf der rechten Seite.

  • Für FULL-Joins ist die Lokalität sehr wichtig.

Unterstützte nicht deterministische Funktionen in vollständiger Aktualisierung

Die folgenden nicht deterministischen Funktionen werden in dynamischen Tabellen unterstützt. Beachten Sie, dass diese Funktionen nur für vollständige Aktualisierungen unterstützt werden. Eine Liste der nicht unterstützten Funktionen für die inkrementelle Aktualisierung finden Sie unter Einschränkungen bei der Unterstützung der inkrementellen Aktualisierung.

Aktualisieren von Daten, wenn dynamische Tabellen von anderen dynamischen Tabellen abhängen

Wenn die Verzögerung einer dynamischen Tabelle als Measure angegeben wird, ermittelt der automatische Aktualisierungsprozess den Zeitplan für die Aktualisierungen auf Grundlage der Zielverzögerungszeiten der dynamischen Tabellen. Der Prozess wählt den Zeitplan aus, der die angestrebten Verzögerungszeiten der Tabellen am besten erfüllt.

Bemerkung

Eine Zielverzögerung ist keine Garantie. Stattdessen ist es ein Ziel, das Snowflake zu erreichen versucht. Die Daten in dynamischen Tabellen werden innerhalb der Zielverzögerung so genau wie möglich aktualisiert. Die Zielverzögerung kann jedoch aufgrund von Faktoren wie der Größe des Warehouses, des Datenumfangs, der Komplexität der Abfrage und ähnlichen Faktoren überschritten werden.

Um die Daten konsistent zu halten, wenn eine dynamische Tabelle von einer anderen abhängt, aktualisiert der Prozess alle dynamischen Tabellen in einem Konto zu kompatiblen Zeiten. Der Zeitpunkt der weniger häufigen Aktualisierungen stimmt mit dem Zeitpunkt der häufigeren Aktualisierungen überein.

Angenommen, eine dynamische Tabelle A hat eine Zielverzögerung von 2 Minuten und fragt eine dynamische Tabelle B ab, die eine Zielverzögerung von 1 Minute hat. Der Prozess könnte festlegen, dass A alle 96 Sekunden aktualisiert werden soll und B alle 48 Sekunden. Im Ergebnis könnte der Prozess folgenden Zeitplan anwenden:

Spezifischer Zeitpunkt

Dynamische Tabellen aktualisiert

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

Das bedeutet, dass Sie bei der Abfrage einer Menge von dynamischen Tabellen, die voneinander abhängen, zu jedem Zeitpunkt denselben „Snapshot“ der Daten in diesen Tabellen abfragen.

Beachten Sie, dass die Zielverzögerung einer dynamischen Tabelle nicht kürzer sein kann als die Zielverzögerung der dynamischen Tabellen, von denen sie abhängt. Folgendes wird angenommen:

  • Die dynamische Tabelle A fragt die dynamischen Tabellen B und C ab.

  • Die dynamische Tabelle B hat eine Zielverzögerung von 5 Minuten.

  • Die dynamische Tabelle C hat eine Zielverzögerung von 1 Minute.

Das bedeutet, dass die Zielverzögerungszeit für A nicht kürzer als 5 Minuten sein darf (d. h. nicht kürzer als die längere der Verzögerungszeiten für B und C).

Wenn Sie die Verzögerung für A auf 5 Minuten einstellen, erstellt der Prozess einen Aktualisierungsplan mit folgenden Zielen:

  • Aktualisiere C häufig genug, um die Verzögerung unter 1 Minute zu halten.

  • Aktualisiere A und B zusammen und häufig genug, um deren Verzögerungen unter 5 Minuten zu halten.

  • Stelle sicher, dass die Aktualisierung von A und B mit einer Aktualisierung von C zusammenfällt, um die Isolation des Snapshots sicherzustellen.

Hinweis: Wenn die Aktualisierungen zu lange dauern, überspringt der Zeitplan möglicherweise Aktualisierungen, um auf dem neuesten Stand zu bleiben. Die Snapshot-Isolation bleibt jedoch erhalten.