Datenschiefe: Optimierung der Verknüpfung mithilfe von Hinweisen

In diesem Artikel wird beschrieben, wie Sie Hinweise zur Datenschiefe verwenden, um die Datenschiefe in einer Tabelle zu mildern. Datenschiefe kann die Abfrageleistung beeinträchtigen.

Hinweis

Hinweise auf schräge Verbindungen sind nicht erforderlich. Die Datenschiefe wird automatisch berücksichtigt, wenn die Ausführung von adaptiven Abfragen (Adaptive Query Execution, AQE) aktiviert ist und spark.sql.adaptive.skewJoin.enabled beide aktiviert sind. Vgl. Ausführung von adaptiven Abfragen.

Was ist Datenschiefe?

Datenschiefe bedeutet, dass die Daten einer Tabelle ungleichmäßig auf die Partitionen im Cluster verteilt sind. Datenschiefe kann die Leistung von Abfragen erheblich verringern, insbesondere bei Abfragen mit Verknüpfungen. Bei Verknüpfungen zwischen großen Tabellen ist das Mischen von Daten erforderlich. Die Datenschiefe kann zu einer extrem unausgeglichenen Arbeitslast im Cluster führen. Wenn eine Abfrage beim Abschließen sehr weniger Aufgaben hängen bleibt (z. B. bei den letzten drei von 200 Aufgaben), ist die Abfrage wahrscheinlich von Datenschiefe betroffen. So überprüfen Sie, ob eine Abfrage von Datenschiefe betroffen ist:

  1. Klicken Sie auf die Phase, die hängen bleibt, und vergewissern Sie sich, dass eine Verknüpfung erfolgt.
  2. Suchen Sie nach Abschluss der Abfrage die Phase, die eine Verknüpfung durchführt, und überprüfen Sie die Verteilung der Taskdauer.
  3. Sortieren Sie die Aufgaben absteigend nach Dauer und überprüfen Sie die obersten Aufgaben. Wenn die Durchführung einer Aufgabe viel länger gedauert hat als die anderer Aufgaben, liegt eine Datenschiefe vor.

Delta Lake in Azure Databricks SQL gestattet die Nutzung von Skew-Hints in Abfragen, um Datenschiefen zu mildern. Mit den Informationen eines Skew Hint kann Databricks Runtime einen besseren Abfrageplan erstellen, der nicht von Datenschiefe betroffen ist.

Konfigurieren von Skew-Hints mit dem Beziehungsnamen

Ein Skew-Hint muss mindestens den Namen der Beziehung mit Datenschiefe enthalten. Eine Beziehung ist eine Tabelle, Ansicht oder Unterabfrage. Alle Verknüpfungen mit dieser Beziehung verwenden dann die Optimierung der Verknüpfung für Datenschiefe.

-- table with skew
SELECT /*+ SKEW('orders') */
  *
  FROM orders, customers
  WHERE c_custId = o_custId

-- subquery with skew
SELECT /*+ SKEW('C1') */
  *
  FROM (SELECT * FROM customers WHERE c_custId < 100) C1, orders
  WHERE C1.c_custId = o_custId

Konfigurieren von Skew-Hints mit Beziehungsnamen und Spaltennamen

Es können mehrere Verknüpfungen für eine Beziehung vorhanden sein, von denen nur einige von Datenschiefe betroffen sind. Die Optimierung der Verknüpfung für Datenschiefe erfordert einen gewissen Mehraufwand, sodass sie im Optimalfall nur bei Bedarf verwendet wird. Zu diesem Zweck akzeptiert der Skew-Hint Spaltennamen. Nur Verknüpfungen mit diesen Spalten verwenden die Optimierung der Verknüpfung für Datenschiefe.

-- single column
SELECT /*+ SKEW('orders', 'o_custId') */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- multiple columns
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId')) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId

Konfigurieren von Skew-Hints mit Beziehungsnamen, Spaltennamen und Datenschiefewerten

Sie können auch Datenschiefewerte im Hinweis angeben. Je nach Abfrage und Daten können die Datenschiefewerte bekannt (z. B. weil sie sich nie ändern) oder leicht zu finden sein. Dadurch wird der Aufwand der Optimierung der Verknüpfung für Datenschiefe reduziert. Andernfalls erkennt Delta Lake sie automatisch.

-- single column, single skew value
SELECT /*+ SKEW('orders', 'o_custId', 0) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- single column, multiple skew values
SELECT /*+ SKEW('orders', 'o_custId', (0, 1, 2)) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId

-- multiple columns, multiple skew values
SELECT /*+ SKEW('orders', ('o_custId', 'o_storeRegionId'), ((0, 1001), (1, 1002))) */
  *
  FROM orders, customers
  WHERE o_custId = c_custId AND o_storeRegionId = c_regionId