Optimalisatie van schendings joins

Gegevensverschil is een voorwaarde waarbij de gegevens van een tabel ongelijk verdeeld zijn over partities in het cluster. Scheefheid van gegevens kan de prestaties van query's ernstig downgraden, met name query's met joins. Voor joins tussen grote tabellen zijn shuffling-gegevens vereist en de scheefheid kan leiden tot een extreme onevenwichtigheid van het werk in het cluster. Het is waarschijnlijk dat scheefheid van gegevens invloed heeft op een query als een query lijkt te zijn vastgelopen en slechts enkele taken heeft uitgevoerd (bijvoorbeeld de laatste drie taken van de 200). Controleren of gegevensverschil van invloed is op een query:

  1. Klik op de fase die is vastgelopen en controleer of er een join wordt gedaan.
  2. Nadat de query is uitgevoerd, gaat u naar de fase die een join uitvoert en controleert u de verdeling van de taakduur.
  3. Sorteer de taken door de duur te verlagen en de eerste paar taken te controleren. Als de ene taak veel langer duurde dan de andere taken, is er scheefheid.

Als u scheefheid wilt intrekken, accepteert Delta Lake op Azure Databricks SQL scheefheidshints in query's. Met de informatie van een scheefheidshint kunnen Databricks Runtime een beter queryplan maken, een plan dat geen last heeft van gegevensverschil.

Notitie

Met Databricks Runtime 7.3 en hoger zijn schefheid van join-hints niet vereist. Scheefheid wordt automatisch opgelost als Adaptive Query Execution (AQE) wordt uitgevoerd spark.sql.adaptive.skewJoin.enabled en beide zijn ingeschakeld. Zie Adaptieve query-uitvoering.

Scheefheidshint configureren met relationele naam

Een scheefheidshint moet ten minste de naam van de relatie met scheefheid bevatten. Een relatie is een tabel, weergave of subquery. Alle joins met deze relatie maken vervolgens gebruik van scheefheidsoptimalisatie.

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

Scheefheidshint configureren met relationele naam- en kolomnamen

Een relatie kan meerdere joins hebben en slechts enkele daarvan zullen last hebben van scheefheid. Scheefheidsoptimalisatie heeft enige overhead, zodat het beter is om deze alleen te gebruiken wanneer dat nodig is. Hiervoor accepteert de scheefheidshint kolomnamen. Alleen joins met deze kolommen maken gebruik van scheefheidsoptimalisatie.

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

Scheefheidshint configureren met relationele naam, kolomnamen en scheefheidswaarden

U kunt ook scheefheidswaarden opgeven in de hint. Afhankelijk van de query en gegevens zijn de scheefheidswaarden mogelijk bekend (bijvoorbeeld omdat ze nooit veranderen) of zijn ze gemakkelijk te vinden. Als u dit doet, vermindert u de overhead van scheefheidsoptimalisatie. Anders detecteert Delta Lake deze 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