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:
|
<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;
Die obige Anweisung kann wie folgt optimiert werden: CREATE DYNAMIC TABLE intermediate
AS
SELECT date_trunc(minute, ts) ts_min, c1 FROM table;
CREATE DYNAMIC TABLE sums
AS
SELECT ts_min, sum(c1) FROM intermediate
GROUP BY 1;
|
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:
|
LATERAL FLATTEN |
Inkrementiert durch Anwendung des Vereinfachungsoperators auf geänderte Zeilen. |
Läuft im Allgemeinen gut. Die Kosten skalieren linear mit dem Umfang der Änderungen. Dieselben allgemeinen Überlegungen wie beim Operator FROM <base table>. |