shuffle-fråga

Frågan shuffle är en semantisk konserveringstransformering som används med en uppsättning operatorer som stöder shuffle strategin. Beroende på vilka data som ingår kan frågor med shuffle strategin ge bättre prestanda. Det är bättre att använda shuffle-frågestrategin shuffle när nyckeln (en join nyckel, summarize nyckel, make-series nyckel eller partition nyckel) har hög kardinalitet och den vanliga operatorfrågan når frågegränserna.

Du kan använda följande operatorer med shuffle-kommandot:

Om du vill använda frågestrategin shuffle lägger du till uttrycket hint.strategy = shuffle eller hint.shufflekey = <key>. När du använder hint.strategy=shuffleblandas operatordata av alla nycklar. Använd det här uttrycket när den sammansatta nyckeln är unik men varje nyckel inte är tillräckligt unik, så du blandar data med alla nycklar i den blandade operatorn.

När du partitionerar data med shuffle-strategin delas datainläsningen på alla klusternoder. Varje nod bearbetar en partition av data. Standardantalet partitioner är lika med antalet klusternoder.

Partitionsnumret kan åsidosättas med hjälp av syntaxen hint.num_partitions = total_partitions, som styr antalet partitioner. Detta är användbart när klustret har ett litet antal klusternoder och standardpartitionsnumret är litet, och frågan misslyckas eller tar lång körningstid.

Anteckning

Om du använder många partitioner kan fler klusterresurser förbrukas och prestanda försämras. Välj partitionsnumret noggrant genom att börja med hint.strategy = shuffle och börja öka partitionerna gradvis.

I vissa fall hint.strategy = shuffle ignoreras och frågan körs inte i shuffle strategin. Detta kan inträffa när:

  • Operatorn join har en annan shuffle-kompatibel operator (join, summarize, make-series eller partition) på vänster sida eller höger sida.
  • Operatorn summarize visas efter en annan shuffle-kompatibel operator (join, summarize, make-series eller partition) i frågan.

Syntax

Med hint.strategy = shuffle

T|DataExpression|joinhint.strategy = shuffle(DataExpression)

T|summarizehint.strategy = shuffleDataExpression

T|Fråga| partition hint.strategy( = shuffleSubQuery)

Med hint.shufflekey = nyckel

T|DataExpression|joinhint.shufflekey = Nyckel(DataExpression)

T|summarizehint.shufflekey = keyDataExpression

T|make-serieshint.shufflekey = keyDataExpression

T|Fråga|partitionsnyckel(hint.shufflekey = underfråga)

Läs mer om syntaxkonventioner.

Parametrar

Namn Typ Obligatorisk Beskrivning
T string ✔️ Den tabellkälla vars data ska bearbetas av operatorn.
DataExpression string Ett implicit eller explicit tabelltransformeringsuttryck.
Query string Ett transformeringsuttryck körs på posterna i T.
Nyckel string Använd en join nyckel, summarize nyckel, make-series nyckel eller partition nyckel.
Underfråga string Ett transformeringsuttryck.

Anteckning

DataExpression eller Query måste anges beroende på den valda syntaxen.

Exempel

Använda summarize med shuffle

Strategifrågan shuffle med summarize operatorn delar belastningen på alla klusternoder, där varje nod bearbetar en partition av data.

StormEvents
| summarize hint.strategy = shuffle count(), avg(InjuriesIndirect) by State
| count 

Resultat

Antal
67

Använd koppling med shuffle

StormEvents
| where State has "West"
| where EventType has "Flood"
| join hint.strategy=shuffle 
    (
    StormEvents
    | where EventType has "Hail"
    | project EpisodeId, State, DamageProperty
    )
    on State
| count

Resultat

Antal
103

Använda make-series med shuffle

StormEvents
| where State has "North"
| make-series hint.shufflekey = State sum(DamageProperty) default = 0 on StartTime in range(datetime(2007-01-01 00:00:00.0000000), datetime(2007-01-31 23:59:00.0000000), 15d) by State

Resultat

Tillstånd sum_DamageProperty StartTime
NORTH DAKOTA [60000,0,0] ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:000:00.0000000Z","2007-01-30T00:00:00.0000000Z"]
NORTH CAROLINA [20000,0,1000] ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:000:00.0000000Z","2007-01-30T00:00:00.0000000Z"]
NORDATLANT [0,0,0] ["2006-12-31T00:00:00.0000000Z","2007-01-15T00:000:00.0000000Z","2007-01-30T00:00:00.0000000Z"]

Använda partition med shuffle

StormEvents
| partition hint.strategy=shuffle by EpisodeId
(
    top 3 by DamageProperty
    | project EpisodeId, State, DamageProperty
)
| count

Resultat

Antal
22345

Jämför hint.strategy=shuffle och hint.shufflekey=key

När du använder hint.strategy=shuffleblandas operatorn med alla nycklar. I följande exempel blandar frågan data med både EpisodeId och EventId som nycklar:

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| join kind = inner hint.strategy=shuffle (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId
| count

Resultat

Antal
14

Följande fråga använder hint.shufflekey = key. Frågan ovan motsvarar den här frågan.

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| join kind = inner hint.shufflekey = EpisodeId hint.shufflekey = EventId (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId

Resultat

Antal
14

Blanda data med flera nycklar

I vissa fall hint.strategy=shuffle ignoreras och frågan körs inte i shuffle-strategin. I följande exempel har kopplingen till exempel en sammanfattning på vänster sida, så om du använder hint.strategy=shuffle används inte shuffle-strategin för frågan:

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| summarize count() by EpisodeId, EventId
| join kind = inner hint.strategy=shuffle (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId

Resultat

EpisodeId EventID ... EpisodeId1 EventId1 ...
1030 4407 ... 1030 4407 ...
1030 13721 ... 1030 13721 ...
2477 12530 ... 2477 12530 ...
2103 10237 ... 2103 10237 ...
2103 10239 ... 2103 10239 ...
... ... ... ... ... ...

Om du vill lösa det här problemet och köra i shuffle-strategi väljer du den nyckel som är gemensam för summarize åtgärderna och join . I det här fallet är EpisodeIdden här nyckeln . Använd tipset hint.shufflekey för att ange shuffle-tangenten på join till hint.shufflekey = EpisodeId:

StormEvents
| where StartTime > datetime(2007-01-01 00:00:00.0000000)
| summarize count() by EpisodeId, EventId
| join kind = inner hint.shufflekey=EpisodeId (StormEvents | where DamageCrops > 62000000) on EpisodeId, EventId

Resultat

EpisodeId EventID ... EpisodeId1 EventId1 ...
1030 4407 ... 1030 4407 ...
1030 13721 ... 1030 13721 ...
2477 12530 ... 2477 12530 ...
2103 10237 ... 2103 10237 ...
2103 10239 ... 2103 10239 ...
... ... ... ... ... ...

Använd summarize with shuffle för att förbättra prestanda

I det här exemplet förbättrar användningen av operatorn summarize med shuffle strategi prestanda. Källtabellen har 150 miljoner poster och kardinaliteten för gruppen efter nyckel är 10 M, som är fördelad över 10 klusternoder.

Med operatorn summarize utan shuffle strategi slutar frågan efter 1:08 och minnesanvändningens topp är ~3 GB:

orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey 
| where o_totalprice < 1000
| count

Resultat

Antal
1086

När du använder shuffle en strategi med summarizeslutar frågan efter ~7 sekunder och minnesanvändningens topp är 0,43 GB:

orders
| summarize hint.strategy = shuffle arg_max(o_orderdate, o_totalprice) by o_custkey 
| where o_totalprice < 1000
| count

Resultat

Antal
1086

I följande exempel visas prestanda för ett kluster som har två klusternoder, med en tabell som har 60 miljoner poster, där kardinaliteten för gruppen efter nyckel är 2 M.

Om du kör frågan utan hint.num_partitions används bara två partitioner (som klusternodnummer) och följande fråga tar ~1:10 minuter:

lineitem 
| summarize hint.strategy = shuffle dcount(l_comment), dcount(l_shipdate) by l_partkey 
| consume

Om partitionsnumret anges till 10 avslutas frågan efter 23 sekunder:

lineitem 
| summarize hint.strategy = shuffle hint.num_partitions = 10 dcount(l_comment), dcount(l_shipdate) by l_partkey 
| consume

Använda koppling med shuffle för att förbättra prestanda

I följande exempel visas hur du kan förbättra prestandan genom att använda shuffle en strategi med operatorn join .

Exemplen samplades i ett kluster med 10 noder där data sprids över alla dessa noder.

Frågans källtabell till vänster har 15 miljoner poster där nyckelns kardinalitet join är ~14 M. Frågans källa på höger sida har 150 miljoner poster och nyckelns join kardinalitet är 10 M. Frågan avslutas efter ~28 sekunder och minnesanvändningen är högst 1,43 GB:

customer
| join
    orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey

När du använder shuffle en strategi med en join operator avslutas frågan efter ~4 sekunder och minnesanvändningens topp är 0,3 GB:

customer
| join
    hint.strategy = shuffle orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey

I ett annat exempel provar vi samma frågor på en större datauppsättning med följande villkor:

  • Källan join till vänster är 150M och nyckelns kardinalitet är 148 M.
  • Höger källa till join är 1,5B och nyckelns kardinalitet är ~100 M.

Frågan med bara operatorn join når gränser och tidsgränsen uppnås efter 4 minuter. Men när du använder shuffle en strategi med operatorn join avslutas frågan efter ~34 sekunder och minnesanvändningen är högst 1,23 GB.

I följande exempel visas förbättringen för ett kluster som har två klusternoder, med en tabell med 60 miljoner poster, där nyckelns join kardinalitet är 2 M. Om du kör frågan utan hint.num_partitions används bara två partitioner (som klusternodnummer) och följande fråga tar ~1:10 minuter:

lineitem
| summarize dcount(l_comment), dcount(l_shipdate) by l_partkey
| join
    hint.shufflekey = l_partkey   part
on $left.l_partkey == $right.p_partkey
| consume

När partitionsnumret anges till 10 avslutas frågan efter 23 sekunder:

lineitem
| summarize dcount(l_comment), dcount(l_shipdate) by l_partkey
| join
    hint.shufflekey = l_partkey  hint.num_partitions = 10    part
on $left.l_partkey == $right.p_partkey
| consume