dotaz náhodného náhodného prohazování
Platí pro: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Dotaz shuffle
je sémantická transformace, která se používá se sadou operátorů, které podporují strategii shuffle
. V závislosti na zahrnutých datech může dotazování na shuffle
strategii přinést lepší výkon. Strategii dotazu náhodného prohazování je lepší použít, když shuffle
má klíč ( join
klíč, summarize
klíč, make-series
klíč nebo partition
klíč) vysokou kardinalitu a dotaz běžného operátora dosáhne limitů dotazu.
Následující operátory můžete použít s příkazem náhodného prohazu:
Pokud chcete použít shuffle
strategii dotazu, přidejte výraz hint.strategy = shuffle
nebo hint.shufflekey = <key>
. Při použití hint.strategy=shuffle
se data operátoru přehazují všemi klíči. Tento výraz použijte, pokud je složený klíč jedinečný, ale každý klíč není dostatečně jedinečný, takže data prohazujete pomocí všech klíčů operátoru prohazování.
Při dělení dat pomocí strategie náhodného prohazování se zatížení dat sdílí na všech uzlech clusteru. Každý uzel zpracovává jeden oddíl dat. Výchozí počet oddílů se rovná počtu uzlů clusteru.
Číslo oddílu lze přepsat pomocí syntaxe hint.num_partitions = total_partitions
, která bude řídit počet oddílů. To je užitečné, když má cluster malý počet uzlů clusteru a výchozí počet oddílů bude malý a dotaz selže nebo trvá dlouhou dobu provádění.
Poznámka:
Použití mnoha oddílů může spotřebovávat více prostředků clusteru a snížit výkon. Číslo oddílu pečlivě vyberte tak, že začnete postupně hint.strategy = shuffle
navyšovat oddíly a začnete je postupně zvětšovat.
V některých případech se ignoruje hint.strategy = shuffle
a dotaz se nespustí ve shuffle
strategii. K tomu může dojít v následujícím případě:
- Operátor
join
má na levé nebo pravé straně jinýshuffle
operátor kompatibilní s operátorem (join
,summarize
make-series
nebopartition
). - Operátor
summarize
se zobrazí za jinýmshuffle
operátorem kompatibilním s dotazem (join
,summarize
make-series
nebopartition
).
Syntaxe
S hint.strategy
= shuffle
T |
DataExpressionhint.strategy
join
|
shuffle
(
= DataExpression )
T = |
summarize
hint.strategy
shuffle
DataExpression
Poddotaz oddílushuffle
hint.strategy
(
= dotazu T |
|
)
S hint.shufflekey
= klíčem
T |
DataExpression = join
|
hint.shufflekey
key (
DataExpression )
T hint.shufflekey
summarize
= |
key DataExpression
T hint.shufflekey
make-series
= |
key DataExpression
Poddotazování |
klíče (
oddílu dotazu |
hint.shufflekey
= )
Přečtěte si další informace o konvencích syntaxe.
Parametry
Název | Type | Požadováno | Popis |
---|---|---|---|
T | string |
✔️ | Tabulkový zdroj, jehož data má operátor zpracovat. |
DataExpression | string |
Implicitní nebo explicitní tabulkový transformační výraz. | |
Dotaz | string |
Transformační výraz se spouští na záznamech T. | |
key | string |
join Použijte klíč, summarize klíč, make-series klíč nebo partition klíč. |
|
Poddotaz | string |
Transformační výraz. |
Poznámka:
V závislosti na zvolené syntaxi musí být zadán datový výraz nebo dotaz .
Příklady
Použití souhrnu s shuffle
shuffle
Dotaz strategie s operátorem summarize
sdílí zatížení na všech uzlech clusteru, kde každý uzel zpracovává jeden oddíl dat.
StormEvents
| summarize hint.strategy = shuffle count(), avg(InjuriesIndirect) by State
| count
Výstup
Počet |
---|
67 |
Použití spojení s 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
Výstup
Počet |
---|
103 |
Použití série make-series s 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
Výstup
State | sum_DamageProperty | Počáteční čas |
---|---|---|
SEVERNÍ DAKOTA | [60000,0,0] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:100:00.000000Z","2007-01-30T00:00:00.000000Z"] |
NORTH CAROLINA | [20000,0,1000] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:100:00.000000Z","2007-01-30T00:00:00.000000Z"] |
ATLANTIC NORTH | [0,0,0] | ["2006-12-31T00:00:00.000000Z","2007-01-15T00:100:00.000000Z","2007-01-30T00:00:00.000000Z"] |
Použití oddílu s shuffle
StormEvents
| partition hint.strategy=shuffle by EpisodeId
(
top 3 by DamageProperty
| project EpisodeId, State, DamageProperty
)
| count
Výstup
Počet |
---|
22345 |
Porovnání hint.strategy=shuffle and hint.shufflekey=key
Když použijete hint.strategy=shuffle
, přehazovaný operátor se prohazuje všemi klíči. V následujícím příkladu dotaz prohazuje data pomocí obou EpisodeId
i EventId
klíčů:
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
Výstup
Počet |
---|
14 |
Následující dotaz používá hint.shufflekey = key
. Výše uvedený dotaz odpovídá tomuto dotazu.
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
Výstup
Počet |
---|
14 |
Náhodné prohazování dat s několika klíči
V některých případech hint.strategy=shuffle
se bude ignorovat a dotaz se nespustí ve strategii náhodného prohazování. Například v následujícím příkladu obsahuje spojení souhrn na levé straně, takže použití hint.strategy=shuffle
nebude u dotazu používat strategii náhodného prohazování:
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
Výstup
EpisodeId | EventId | ... | EpizodaId1 | Id události 1 | ... |
---|---|---|---|---|---|
1030 | 4407 | ... | 1030 | 4407 | ... |
1030 | 13721 | ... | 1030 | 13721 | ... |
2477 | 12530 | ... | 2477 | 12530 | ... |
2103 | 10237 | ... | 2103 | 10237 | ... |
2103 | 10239 | ... | 2103 | 10239 | ... |
... | ... | ... | ... | ... | ... |
Pokud chcete tento problém překonat a spustit ve strategii náhodného prohazování, zvolte klíč, který je běžný pro summarize
operace a join
operace. V tomto případě je EpisodeId
tento klíč . Pomocí nápovědy hint.shufflekey
zadejte klávesu pro náhodné prohazovací klávesy hint.shufflekey = EpisodeId
join
na :
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
Výstup
EpisodeId | EventId | ... | EpizodaId1 | Id události 1 | ... |
---|---|---|---|---|---|
1030 | 4407 | ... | 1030 | 4407 | ... |
1030 | 13721 | ... | 1030 | 13721 | ... |
2477 | 12530 | ... | 2477 | 12530 | ... |
2103 | 10237 | ... | 2103 | 10237 | ... |
2103 | 10239 | ... | 2103 | 10239 | ... |
... | ... | ... | ... | ... | ... |
Použití sumarizace pomocí náhodného náhodného prohazu ke zlepšení výkonu
V tomto příkladu použití operátora summarize
se shuffle
strategií zlepšuje výkon. Zdrojová tabulka obsahuje 150M záznamů a kardinalita skupiny podle klíče je 10 M, což je rozdělené do 10 uzlů clusteru.
Použití summarize
operátoru bez shuffle
strategie skončí dotaz po 1:08 a špička využití paměti je ~3 GB:
orders
| summarize arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
Výstup
Počet |
---|
1086 |
Při použití shuffle
strategie s summarize
dotazem skončí po ~7 sekundách a špička využití paměti je 0,43 GB:
orders
| summarize hint.strategy = shuffle arg_max(o_orderdate, o_totalprice) by o_custkey
| where o_totalprice < 1000
| count
Výstup
Počet |
---|
1086 |
Následující příklad ukazuje výkon clusteru se dvěma uzly clusteru s tabulkou se 60M záznamy, kde kardinalita skupiny podle klíče je 2M.
Spuštění dotazu bez hint.num_partitions
použití pouze dvou oddílů (jako čísla uzlů clusteru) a následující dotaz bude trvat přibližně 1:10 min:
lineitem
| summarize hint.strategy = shuffle dcount(l_comment), dcount(l_shipdate) by l_partkey
| consume
Pokud nastavíte číslo oddílů na 10, dotaz skončí po 23 sekundách:
lineitem
| summarize hint.strategy = shuffle hint.num_partitions = 10 dcount(l_comment), dcount(l_shipdate) by l_partkey
| consume
Použití spojení s shufflem ke zlepšení výkonu
Následující příklad ukazuje, jak použití shuffle
strategie s operátorem join
zlepšuje výkon.
Příklady byly vzorkovány v clusteru s 10 uzly, ve kterých jsou data rozložena do všech těchto uzlů.
Zdrojová tabulka dotazu na levé straně obsahuje 15M záznamů, kde kardinalita join
klíče je ~14M. Zdroj pravé strany dotazu má 150M záznamů a kardinalita join
klíče je 10 M. Dotaz končí po ~28 sekundách a špička využití paměti je 1,43 GB:
customer
| join
orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
Při použití shuffle
strategie s operátorem join
skončí dotaz po ~4 sekundách a špička využití paměti je 0,3 GB:
customer
| join
hint.strategy = shuffle orders
on $left.c_custkey == $right.o_custkey
| summarize sum(c_acctbal) by c_nationkey
V jiném příkladu vyzkoušíme stejné dotazy na větší datovou sadu s následujícími podmínkami:
- Levý zdroj klíče
join
je 150M a kardinalita klíče je 148 M. - Pravý zdroj
join
klíče je 1,5B a kardinalita klíče je ~100 M.
Dotaz s pouhým operátorem join
dosáhne limitů a vyprší časový limit po 4 minutách. Při použití shuffle
strategie s operátorem join
však dotaz skončí po ~34 sekundách a špička využití paměti je 1,23 GB.
Následující příklad ukazuje vylepšení clusteru se dvěma uzly clusteru s tabulkou 60M záznamů, kde kardinalita join
klíče je 2M.
Spuštění dotazu bez hint.num_partitions
použití pouze dvou oddílů (jako čísla uzlů clusteru) a následující dotaz bude trvat přibližně 1:10 min:
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
Při nastavování čísla oddílů na 10 se dotaz ukončí po 23 sekundách:
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