zapytanie shuffle

Zapytanie shuffle jest semantyczną transformacją używaną z zestawem operatorów, które obsługują strategię shuffle . W zależności od zaangażowanych danych wykonywanie zapytań przy użyciu shuffle strategii może przynieść lepszą wydajność. Lepiej jest użyć strategii zapytania shuffle, gdy shuffle klucz ( join klucz, summarize klucz, make-series klucz lub partition klucz) ma wysoką kardynalność, a zapytanie operatora regularnego osiąga limity zapytań.

Za pomocą polecenia shuffle można użyć następujących operatorów:

Aby użyć shuffle strategii zapytania, dodaj wyrażenie hint.strategy = shuffle lub hint.shufflekey = <key>. Gdy używasz hint.strategy=shufflemetody , dane operatora zostaną przetasowane przez wszystkie klucze. Użyj tego wyrażenia, gdy klucz złożony jest unikatowy, ale każdy klucz nie jest wystarczająco unikatowy, dlatego przetasujesz dane przy użyciu wszystkich kluczy operatora shuffled.

Podczas partycjonowania danych za pomocą strategii mieszania obciążenie danych jest współużytkowane we wszystkich węzłach klastra. Każdy węzeł przetwarza jedną partycję danych. Domyślna liczba partycji jest równa liczbie węzłów klastra.

Numer partycji można zastąpić przy użyciu składni hint.num_partitions = total_partitions, która będzie kontrolować liczbę partycji. Jest to przydatne, gdy klaster ma niewielką liczbę węzłów klastra, a domyślna liczba partycji będzie mała, a zapytanie kończy się niepowodzeniem lub trwa długi czas wykonywania.

Uwaga

Użycie wielu partycji może zużywać więcej zasobów klastra i obniżyć wydajność. Starannie wybierz numer partycji, zaczynając od hint.strategy = shuffle i stopniowo zwiększając partycje.

W niektórych przypadkach hint.strategy = shuffle element jest ignorowany, a zapytanie nie zostanie uruchomione w shuffle strategii. Może się to zdarzyć, gdy:

  • Operator join ma inny shuffleoperator zgodny (join, summarizelub make-seriespartition) po lewej stronie lub po prawej stronie.
  • Operator summarize pojawia się po innym shuffleoperatorze zgodnym z programem (join, summarizelub make-seriespartition) w zapytaniu.

Składnia

Z hint.strategy = shuffle

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

T|summarizehint.strategy = shuffleDataExpression

T|Kwerendy|podzapytywanie partycjihint.strategy = shuffle()

Z kluczemhint.shufflekey =

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

T|summarizehint.shufflekey = keyDataExpression

T|make-serieshint.shufflekey = keyDataExpression

T|Kwerendy|podzapytywanieklucza( partycji hint.shufflekey = )

Dowiedz się więcej o konwencjach składniowych.

Parametry

Nazwa Typ Wymagane Opis
T string ✔️ Tabelaryczne źródło, którego dane mają być przetwarzane przez operatora.
DataExpression string Niejawne lub jawne wyrażenie przekształcenia tabelarycznego.
Zapytanie string Wyrażenie przekształcenia jest uruchamiane na rekordach języka T.
Klucz string join Użyj klucza, summarize klucza, make-series klucza lub partition klucza.
Podkwerenda string Wyrażenie przekształcenia.

Uwaga

W zależności od wybranej składni należy określić wartość DataExpression lub Query .

Przykłady

Używanie podsumowania z funkcją shuffle

shuffle Zapytanie strategii z operatorem summarize współdzieli obciążenie wszystkich węzłów klastra, gdzie każdy węzeł przetwarza jedną partycję danych.

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

Dane wyjściowe

Liczba
67

Używanie sprzężenia z mieszania

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

Dane wyjściowe

Liczba
103

Używanie serii make-series z mieszania

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

Dane wyjściowe

Stan sum_DamageProperty StartTime
DAKOTA PÓŁNOCNA [60000,0,0] ["2006-12-31T00:00:00.000000Z","2007-01-15T00:00:00.000000Z","2007-01-30T00:00:00.000000Z"]
KAROLINA PÓŁNOCNA [20000,0,1000] ["2006-12-31T00:00:00.000000Z","2007-01-15T00:00:00.000000Z","2007-01-30T00:00:00.000000Z"]
PÓŁNOC ATLANTYCKIA [0,0,0] ["2006-12-31T00:00:00.000000Z","2007-01-15T00:00:00.000000Z","2007-01-30T00:00:00.000000Z"]

Używanie partycji z mieszania

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

Dane wyjściowe

Liczba
22345

Porównaj element hint.strategy=shuffle i hint.shufflekey=key

W przypadku użycia hint.strategy=shuffleoperatora shuffled operator zostanie przetasowany przez wszystkie klucze. W poniższym przykładzie zapytanie przetasuje dane przy użyciu klawiszy EpisodeId i EventId jako kluczy:

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

Dane wyjściowe

Liczba
14

Poniższe zapytanie używa metody hint.shufflekey = key. Powyższe zapytanie jest równoważne temu zapytaniu.

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

Dane wyjściowe

Liczba
14

Mieszanie danych przy użyciu wielu kluczy

W niektórych przypadkach hint.strategy=shuffle element zostanie zignorowany, a zapytanie nie zostanie uruchomione w strategii mieszania. Na przykład w poniższym przykładzie sprzężenie zawiera podsumowanie po lewej stronie, więc użycie hint.strategy=shuffle metody nie spowoduje zastosowania strategii mieszania do zapytania:

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

Dane wyjściowe

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

Aby rozwiązać ten problem i uruchomić strategię mieszania, wybierz klucz wspólny dla summarize operacji i join . W tym przypadku kluczem jest EpisodeId. Użyj wskazówek hint.shufflekey , aby określić klucz mieszania w obiekcie join do 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

Dane wyjściowe

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

Używanie funkcji podsumowania z mieszania w celu zwiększenia wydajności

W tym przykładzie summarize użycie operatora ze strategią shuffle zwiększa wydajność. Tabela źródłowa ma 150 mln rekordów, a kardynalność grupy według klucza wynosi 10 mln, co jest rozłożone na 10 węzłów klastra.

Użycie summarize operatora bez shuffle strategii, zapytanie kończy się po 1:08, a szczyt użycia pamięci wynosi ok. 3 GB:

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

Dane wyjściowe

Liczba
1086

Podczas korzystania ze shuffle strategii z summarizeprogramem zapytanie kończy się po około 7 sekundach, a szczyt użycia pamięci wynosi 0,43 GB:

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

Dane wyjściowe

Liczba
1086

W poniższym przykładzie pokazano wydajność klastra, który ma dwa węzły klastra, z tabelą zawierającą rekordy 60M, gdzie kardynalność grupy według klucza wynosi 2 mln.

Uruchomienie zapytania bez hint.num_partitions będzie używać tylko dwóch partycji (jako numer węzłów klastra), a następujące zapytanie zajmie około 1:10 minut:

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

Jeśli ustawisz liczbę partycji na 10, zapytanie zakończy się po 23 sekundach:

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

Używanie sprzężenia z mieszania w celu zwiększenia wydajności

W poniższym przykładzie pokazano, jak użycie shuffle strategii z operatorem join zwiększa wydajność.

Przykłady zostały próbkowane w klastrze z 10 węzłami, w których dane są rozłożone na wszystkie te węzły.

Tabela źródłowa po lewej stronie zapytania zawiera 15 mln rekordów, w których kardynalność join klucza wynosi ok. 14 mln. Źródło po prawej stronie zapytania ma 150M rekordów, a kardynalność join klucza to 10 mln. Zapytanie kończy się po około 28 sekundach, a szczyt użycia pamięci wynosi 1,43 GB:

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

W przypadku korzystania ze shuffle strategii z operatorem join zapytanie kończy się po około 4 sekundach, a szczyt użycia pamięci wynosi 0,3 GB:

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

W innym przykładzie spróbujemy wykonać te same zapytania dla większego zestawu danych z następującymi warunkami:

  • Lewe źródło wartości join to 150M, a kardynalność klucza to 148M.
  • Prawe źródło wartości join to 1,5B, a kardynalność klucza wynosi ok. 100 mln.

Zapytanie z operatorem join osiąga limity i limity czasu po 4 minutach. Jednak w przypadku korzystania shuffle ze strategii z operatorem join zapytanie kończy się po około 34 sekundach, a szczyt użycia pamięci wynosi 1,23 GB.

W poniższym przykładzie pokazano ulepszenie klastra z dwoma węzłami klastra z tabelą 60M rekordów, gdzie kardynalność join klucza wynosi 2 mln. Uruchomienie zapytania bez hint.num_partitions będzie używać tylko dwóch partycji (jako numer węzłów klastra), a następujące zapytanie zajmie około 1:10 minut:

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

Podczas ustawiania liczby partycji na 10 zapytanie zakończy się po 23 sekundach:

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