Condividi tramite


Ottimizzazione dell'asimmetria del join tramite hint di asimmetria

Importante

Questa documentazione è stata ritirata e potrebbe non essere aggiornata. I prodotti, i servizi o le tecnologie menzionati in questo contenuto non sono più supportati.

Gli hint di join sbilanciato non sono obbligatori. Databricks gestisce l'asimmetria per impostazione predefinita usando l'esecuzione di query adattive (AQE). Vedi esecuzione di query adattive.

Nota

spark.sql.adaptive.skewJoin.enabled deve essere True, ovvero l'impostazione predefinita in Azure Databricks.

Che cos'è l'asimmetria dei dati?

L'asimmetria dei dati è una condizione in cui i dati di una tabella vengono distribuiti in modo non uniforme tra le partizioni nel cluster. L'asimmetria dei dati può ridurre gravemente le prestazioni delle query, in particolare quelle con join. I join tra tabelle di grandi dimensioni richiedono lo spostamento dei dati e lo sbilanciamento può causare uno squilibrio estremo del lavoro nel cluster. È probabile che l'asimmetria dei dati influisca su una richiesta se una richiesta sembra essere bloccata nel completare pochissime attività, ad esempio le ultime 3 attività su 200. Per verificare che l'asimmetria dei dati influisca su una query:

  1. Fare clic sulla fase bloccata e verificare che stia eseguendo un join.
  2. Al termine della query, individuare la fase che esegue un join e controllare la distribuzione della durata dell'attività.
  3. Ordinare le attività riducendo la durata e controllare le prime attività. Se un'attività ha richiesto molto più tempo rispetto alle altre attività, si verifica un'asimmetria.

Per migliorare l'asimmetria, Delta Lake in Azure Databricks SQL accetta suggerimenti di asimmetria nelle query. Con le informazioni di un hint di skew, Databricks Runtime può costruire un piano di interrogazione migliore, che non risente della distribuzione asimmetrica dei dati.

Configurare il suggerimento di asimmetria con il nome della relazione

Un hint di asimmetria deve contenere almeno il nome della relazione che presenta asimmetria. Una relazione è una tabella, una vista o una sottoquery. Tutti i join con questa relazione usano quindi l'ottimizzazione del join con dati sbilanciati.

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

Configurare l'hint di asimmetria con il nome della relazione e i nomi delle colonne

Potrebbero esserci più join su una relazione e solo alcuni di essi soffriranno di asimmetria. L'ottimizzazione del join con asimmetria comporta un certo sovraccarico, quindi è preferibile usarla solo quando necessario. A questo scopo, l'hint skew accetta nomi di colonna. Solo i join con queste colonne usano l'ottimizzazione del join con sbilanciamento.

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

Configurare l'hint di asimmetria con il nome della relazione, i nomi delle colonne e i valori di asimmetria

È anche possibile specificare valori di asimmetria nell'hint. A seconda della query e dei dati, i valori di asimmetria potrebbero essere noti (ad esempio, perché non cambiano mai) o potrebbero essere facili da individuare. In questo modo si riduce il sovraccarico dell'ottimizzazione dell'asimmetria del join. In caso contrario, Delta Lake li rileva automaticamente.

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